案例: 商场收银软件 根据用户所购买的商品的单价和数量,向客户收费
1. 利用简单工厂模式实现
工厂类
class CashFactory{
public static CashSuper createCashAccept(String type){
CashSuper cs=null;
switch(type){
case "正常收费": cs=new CashNormal(); break;
case "满300送100”: cs=new CashReturn("300","100"); break;
case "打8折": cs=new CashRebate("0.8"); break;
}
return cs;
}
}
现金收费抽象类
abstract class CashSuper{
public abstract double acceptCash(double money);
}
正常收费子类
class CashNormal:CashSuper
{
public override double accpetCash(double money){
return money;
}
}
打折收费子类
返利收费子类
但是,工厂可能经常性地更改打折额度和返利额度,每次都需要改动这个工厂。
2.策略模式(Strategy)
定义了算法家族,分别封装起来,让它们之间可以互相替换,让算法的变化不会影响到使用算法的客户。
有一个strategy父类 具体的strategy继承strategy
Context类维护一个对strategy的引用
对于上述例子。 cashSuper、cashNormal、cashRebate、cashReturn 都无需改变
新增一个cashContext类来持有对cashSuper的引用
Class CashContext{
private CashSuper cs;
public CashContext(CashSuper csuper){
this.cs=csuper;
}
public double getResult(double money){
return cs.acceptCash(money);
}
}
但是这样做需在客户端判断用哪一个算法
3.策略模式与工厂模式结合
//改进CashContext,将复杂的判断放到Context类中
class CashContext{
private CashSuper cs=null;
public CashContext(String type){
switch "正常收费":
CashNormal cn=new CashNormal();
cs=cn;
break;
switch "打8折": ... ...
switch "满300减100”:.......
}
public double getResult(double money){
return cs.acceptCash(money);
}
}
4. 简单工厂模式 和 若将工厂和策略相结合的 不同
//简单工厂模式的用法
CashSuper cSuper= CashFactory.createCashAccept(....);
...=cSuper.getResult();
//二者结合的用法
CashContext cSuper = new CashContext(....);
...=cSuper.getResult();
5.策略模式的优点
1.减少了各种算法类和使用算法类之间的耦合
2.策略模式的Strategy类层次为Context定义了一系列可供重用的算法或行为。
3.简化了单元测试,因为每个算法都有自己的类,修改一个也不会影响其他的
只要在不同时间应用不同的业务规则都可以选择策略模式
策略模式与工厂模式相结合可以减轻客户端的判断职责
但是 Context类中还是用到了switch....所以仍然还有改进的办法