在说明策略模式之前,先看一个打折促销的例子
一家超市进行打折促销:促销形式分别有:“打8折”和“满300减100”,该怎么实现?
用简易的工厂模式:
创建收费接口
public interface CashSuper { double acceptCash(double money); }
创建正常收费子类:实现收费接口
public class CashNormal implements CashSuper { @Override public double acceptCash(double money) { return money; } }
创建打折收费子类:实现收费接口
public class CashRebate implements CashSuper { private double moneyRebate = 1d; public CashRebate(double moneyRebate) { this.moneyRebate = moneyRebate; } @Override public double acceptCash(double money) { return money*moneyRebate; } }
创建返利收费子类:实现收费接口
public class CashReturn implements CashSuper { private double moneyCondition = 0.0d; private double moneyReturn =0.0d; public CashReturn(double moneyCondition, double moneyReturn) { super(); this.moneyCondition = moneyCondition; this.moneyReturn = moneyReturn; } @Override public double acceptCash(double money) { double result = money; if(money>=moneyCondition){ result = money-Math.floor(money/moneyCondition)*moneyReturn; } return result; } }
创建收费工厂类
public class CashFactory { public static CashSuper createCashAccept(String type,double moneyCondition,double moneyReturn,double moneyRebate){ CashSuper cs = null; switch (type) { case "正常收费": cs = new CashNormal(); break; case "满X返Y": cs = new CashReturn(moneyCondition, moneyReturn); break; case "打X折": cs = new CashRebate(moneyRebate); break; default: break; } return cs; } }
模拟打折测试
public class Test { public static void main(String[] args) { double moneyNormal = 300; CashSuper cs1 = CashFactory.createCashAccept("正常收费",0,0,0); double result = cs1.acceptCash(moneyNormal); System.out.println("正常收费"+moneyNormal+"元的结果:"+result); double moneyRebate = 0.8; CashSuper cs2 = CashFactory.createCashAccept("打X折",0,0,moneyRebate); double result2 = cs2.acceptCash(moneyNormal); System.out.println(moneyNormal+"元打"+0.8*10+"折的结果:"+result2); double moneyCondition = 300; double moneyReturn =100; CashSuper cs3 = CashFactory.createCashAccept("满X返Y",moneyCondition,moneyReturn,0); double result3 = cs3.acceptCash(moneyNormal); System.out.println(moneyNormal+"元进行满"+moneyCondition+"减"+moneyReturn+"元的结果:"+result3); } }
输出结果:
正常收费300.0元的结果:300.0 300.0元打8.0折的结果:240.0 300.0元进行满300.0减100.0折的结果:200.0
策略模式介绍:http://www.runoob.com/design-pattern/strategy-pattern.html
策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
根据策略模式修改后的代码
修改 CashFactory 类,并在类中添加 getResult() 方法,在 getResult() 方法内调用 acceptCash() 方法
public class CashContext { CashSuper cs = null; public CashContext(String type,double moneyCondition,double moneyReturn,double moneyRebate){ switch (type) { case "正常收费": cs = new CashNormal(); break; case "满X返Y": cs = new CashReturn(moneyCondition, moneyReturn); break; case "打X折": cs = new CashRebate(moneyRebate); break; default: break; } } public double getResult(double money){ return cs.acceptCash(money); } }
模拟打折测试
public class Test { public static void main(String[] args) { double moneyNormal = 300; CashContext cc = new CashContext("正常收费",0,0,0); double result = cc.getResult(moneyNormal); System.out.println("正常收费"+moneyNormal+"元的结果:"+result); double moneyRebate = 0.8; CashContext cc2 = new CashContext("打X折",0,0,moneyRebate); double result2 = cc2.getResult(moneyNormal); System.out.println(moneyNormal+"元打"+0.8*10+"折的结果:"+result2); double moneyCondition = 300; double moneyReturn =100; CashContext cc3 = new CashContext("满X返Y",moneyCondition,moneyReturn,0); double result3 = cc3.getResult(moneyNormal); System.out.println(moneyNormal+"元进行满"+moneyCondition+"减"+moneyReturn+"元的结果:"+result3); } }
对比CashFactory和CashContext类,区别在于CashContext新增了 getResult() 方法,并在其内部调用收费类的 acceptCash() 方法,main方法不直接调用收费类的 acceptCash() 方法。
工厂模式侧重于创建类,策略模式侧重于行为的选择。
在打折促销的案例中,收费类都实现了CashSuper接口,并重写 acceptCash() 方法,我们可以在不同的场景中调用对应的类中的 acceptCash() 方法。但我们真正在乎的是 acceptCash() 方法。哪怕收费类中有一万个其他的方法,我们也只需要这一个方法。
因为侧重点的不同,策略模式并不需要暴露完整的收费类,对收费类进行封装,暴露出 acceptCash() 方法即可。
参考网上的文章:策略模式和工厂模式的区别
https://blog.csdn.net/gaibian0823/article/details/27842443