策略模式——StrategyPattern
策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式优点为算法变化时不会影响算法的客户。
基本实现方法是:
- 策略基类:为某一类功能设置一个策略基类,使用抽象方法,定义所有支持的算法的公共接口
- 策略类:继承策略基类,封装具体的算法或行为。
- 上下文类:用于选择使用哪一个策略类,并实现调用其对应的策略类的方法。
我的理解是:
- 策略模式的重点是:在上下文类中,直接传入需要的对象,通过上下文类控制这个对象,调用这个对象的方法。
- 简单工厂模式的重点是:输入条件,通过工厂返回一个需要的对象。并将这个对象直接赋给基类。
例子:现有一商场进行促销,可对某商品采用打折促销方式,或采用满一定金额减免一部分金额的促销方案。
促销方案可以灵活的变化。
策略基类 CashSuper
1 public abstract class CashSuper { 2 public abstract double acceptCash(double money); 3 }
正常收银策略类 CashNormal
1 public class CashNormal extends CashSuper { 2 @Override 3 public double acceptCash(double money) { 4 return money; 5 } 6 }
打折收银策略类 CashRebate
1 public class CashRebate extends CashSuper { 2 private double moneyRebate=1d; 3 public CashRebate(String moneyRebate) 4 { 5 this.moneyRebate=Double.parseDouble(moneyRebate); 6 } 7 8 @Override 9 public double acceptCash(double money) { 10 return money*moneyRebate; 11 } 12 }
满减收银策略类 CashReturn
1 public class CashReturn extends CashSuper { 2 private double moneyCondition=0.0d; 3 private double moneyReturn=0.0d; 4 public CashReturn(String moneyConditon,String moneyReturn) 5 { 6 this.moneyCondition=Double.parseDouble(moneyConditon); 7 this.moneyReturn=Double.parseDouble(moneyReturn); 8 } 9 @Override 10 public double acceptCash(double money) { 11 double result=money; 12 if(money>=moneyCondition) 13 result=money-(int)(money/moneyCondition)*moneyReturn; 14 return result; 15 } 16 }
上下文类 CashContext
1 public class CashContext { 2 private CashSuper cashSuper; 3 public CashContext(CashSuper cashSuper) 4 { 5 this.cashSuper=cashSuper; 6 } 7 public double getReslut(double money) 8 { 9 return cashSuper.acceptCash(money); 10 } 11 }
主函数
1 public class Client { 2 public static void main(String[] args) { 3 String conditon=""; 4 double money=900; 5 // conditon="正常收费"; 6 // conditon="八折"; 7 conditon="满200减100"; 8 9 /** 10 * 正常策略模式 11 */ 12 CashContext cashContext=null; 13 switch (conditon) 14 { 15 case "正常收费": 16 cashContext=new CashContext(new CashNormal());break; 17 case "八折": 18 cashContext=new CashContext(new CashRebate("0.8"));break; 19 case "满200减100": 20 cashContext=new CashContext(new CashReturn("200","100"));break; 21 } 22 System.out.println("原价:"+money+" "+conditon+"后:"+cashContext.getReslut(money)); 23 24 } 25 }
这种方法 在主函数中 通过swich函数判断需要实现哪种功能,然后new出相应对象传入上下文类中,再调用上下文类的方法就可以执行需要的方法。
但这种形式会让客户端去判断使用哪一个算法,可以使用策略模式与简单工厂模式相结合的方法进行改进。
策略模式与简单工厂模式相结合
与工厂模式结合的上下文类 CashContextWithFactory
1 /** 2 * 策略与工厂结合 3 */ 4 public class CashContextWithFactory { 5 private CashSuper cashSuper; 6 public CashContextWithFactory(String conditon) 7 { 8 switch (conditon) 9 { 10 case "正常收费": 11 this.cashSuper=new CashNormal();break; 12 case "八折": 13 this.cashSuper=new CashRebate("0.8");break; 14 case "满200减100": 15 this.cashSuper=new CashReturn("200","100");break; 16 } 17 } 18 public double getReslut(double money) 19 { 20 return cashSuper.acceptCash(money); 21 } 22 }
主函数
1 public class Client { 2 public static void main(String[] args) { 3 String conditon=""; 4 double money=900; 5 // conditon="正常收费"; 6 // conditon="八折"; 7 conditon="满200减100"; 8 9 /** 10 * 策略模式与简单工厂结合 11 */ 12 CashContextWithFactory cashContextWithFactory=new CashContextWithFactory(conditon); 13 System.out.println("原价:"+money+" "+conditon+"后:"+cashContextWithFactory.getReslut(money)); 14 } 15 }
这样就将方法判断转移到了上下文类中。
相关代码:https://github.com/lancelee98/DesignPattern/tree/master/src/StrategyPattern