策略模式
开始
商场的收银软件:业务员根据购买商品的单价和数量向客户收费
基础的实现:就是遍历后累加
变更
超时推出了全场打八折活动
- 前端添加一个变量标识活动,计算结果根据活动标识做响应的打折
人气多了,改变了活动规则,满300打8折
简单工厂模式虽然解决对象的创建问题,但是工厂类中需要根据收费方式创建对象,如果活动变化大,每次维护和扩展都需要改工厂类
策略模式
策略模式(Strategy)属于对象行为型设计模式,主要是定义一系列的算法,把这些算法一个个封装成拥有共同接口的单独的类,并且使它们之间可以互换。
策略模式使这些算法在客户端调用它们的时候能够互不影响地变化。这里的算法不要狭义的理解为数据结构中算法,可以理解为不同的业务处理方法。
这种做法会带来什么样的好处呢? 它将算法的使用和算法本身分离,即将变化的具体算法封装了起来,降低了代码的耦合度,系统业务策略的更变仅需少量修改。 算法被提取出来,这样可以使算法得到重用,这种情况还可以考虑使用享元模式来共享算法对象,来减少系统开销(但要注意使用享元模式的建议条件)。
结构
策略模式由三个角色组成:
- 算法使用环境(Context)角色:算法被引用到这里和一些其它的与环境有关的操作一起 来完成任务。
- 抽象策略(Strategy)角色:规定了所有具体策略角色所需的接口。在 java 它通常由接口 或者抽象类来实现。
- 具体策略(Concrete Strategy)角色:实现了抽象策略角色定义的接口。
实现
CashSuper就是一个抽象策略,他的实现类就是具体策略
在原有基础上添加Content类
1
2
3
4
5
6
7
8
9
10
11
12class CashContext{
private CashSuper cs;
// 构造方法传入具体的收费策略
public CashContext(CashSuper csuper){
this.cs = csuper;
}
pulic double getResult(double money){
// 根据收费策略运算
return cs.acceptCash(money);
}
}
问题
策略模式后,客户端创建CashContext后需要指定CashSuper,需要客户端去判断用哪一个算法
1
2
3
4
5
6CashContext cc = null;
switch (item){
case "打八折": cc = new CashRebate("0.8");
// ....
}
double total = cc.getResult(1000);
结合工厂模式
使用工厂模式与策略模式结合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class CashContext{
private CashSuper cs;
// 构造方法传入具体的收费类型
public CashContext(CashSuper csuper){
switch (item){
// 应用简单工厂: 将实例化策略放到context类中
case "打八折": this.cs = new CashRebate("0.8");break;
// ....
}
}
pulic double getResult(double money){
// 根据收费策略运算
return cs.acceptCash(money);
}
}客户端使用
1
2
3
4
5
6// 简单工厂
CashSuper cs = CashFactory.createCashAccept("打八折");
cs.getResult(money);
// 简单工厂+策略模式
new CashContext("打八折").getResult(money);简单工程模式需要客户端认识二个类 CashSuper, CashFactory
策略模式与简单工厂结合后,只需要认识CashContext 就可以,耦合度降低了,CashContext#getResult方法使得具体的收费方式也与客户端分离
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 凉月の博客!
评论