标签:相同 blank rate 多重 不同 log exti member lan
在阎宏博士的《JAVA与模式》一书中开头是这样描述策略(Strategy)模式的:
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
策略模式把一个系列的算法封装到一个系列的具体策略类里面,作为一个抽象策略类的子类或策略接口的实现类。简单地说:准备一组算法,并将每一个算法封装起来,使它们可以互换。
示意性UML图:
这个模式涉及到3个角色:
环境(Context)角色:持有一个Strategy抽象策略类或策略接口的引用。
抽象策略(Strategy)角色:这是一个抽象角色,由一个接口或抽象类实现。此角色声明所有的具体策略类需要重写的方法。
具体策略(Concrete Strategy)角色:封装了相关的算法或行为。
示意性实例:
环境角色
1 public class Context { 2 // 持有一个具体策略的对象 3 private Strategy strategy; 4 /** 5 * 构造函数,传入一个具体策略对象 6 * @param strategy 具体策略对象 7 */ 8 public Context(Strategy strategy){ 9 this.strategy = strategy; 10 } 11 /** 12 * 策略方法 13 */ 14 public void contextInterface(){ 15 16 strategy.strategyInterface(); 17 } 18 19 }
抽象策略角色
1 public interface Strategy { 2 /** 3 * 策略方法 4 */ 5 public void strategyInterface(); 6 }
具体策略角色
1 public class ConcreteStrategyA implements Strategy { 2 3 @Override 4 public void strategyInterface() { 5 // 相关的业务 6 } 7 8 }
1 public class ConcreteStrategyB implements Strategy { 2 3 @Override 4 public void strategyInterface() { 5 // 相关的业务 6 } 7 8 }
1 public class ConcreteStrategyC implements Strategy { 2 3 @Override 4 public void strategyInterface() { 5 // 相关的业务 6 } 7 8 }
使用场景实例:
假设某个网站销售各种书籍,对初级会员没有提供折扣,对中级会员提供每本10%的促销折扣,对高级会员提供每本20%的促销折扣。
折扣是根据以下的3个算法中的1个进行的:
算法1:对初级会员没有提供折扣。
算法2:对中级会员提供10%的促销折扣。
算法3:对高级会员提供20%的促销折扣。
该实例的UML图:
折扣接口
1 public interface MemberStrategy { 2 /** 3 * 计算图书的价格 4 * @param booksPrice 图书的原价 5 * @return 计算出打折后的价格 6 */ 7 public double calcPrice(double booksPrice); 8 }
初级会员折扣实现类
1 public class PrimaryMemberStrategy implements MemberStrategy { 2 3 @Override 4 public double calcPrice(double booksPrice) { 5 6 System.out.println("对于初级会员的没有折扣"); 7 return booksPrice; 8 } 9 10 }
中级会员折扣实现类
1 public class IntermediateMemberStrategy implements MemberStrategy { 2 3 @Override 4 public double calcPrice(double booksPrice) { 5 6 System.out.println("对于中级会员的折扣为10%"); 7 return booksPrice * 0.9; 8 } 9 10 }
高级会员折扣实现类
1 public class AdvancedMemberStrategy implements MemberStrategy { 2 3 @Override 4 public double calcPrice(double booksPrice) { 5 6 System.out.println("对于高级会员的折扣为20%"); 7 return booksPrice * 0.8; 8 } 9 }
价格类
1 public class Price { 2 // 持有一个具体的策略对象 3 private MemberStrategy strategy; 4 /** 5 * 构造函数,传入一个具体的策略对象 6 * @param strategy 具体的策略对象 7 */ 8 public Price(MemberStrategy strategy){ 9 this.strategy = strategy; 10 } 11 12 /** 13 * 计算图书的价格 14 * @param booksPrice 图书的原价 15 * @return 计算出打折后的价格 16 */ 17 public double quote(double booksPrice){ 18 return this.strategy.calcPrice(booksPrice); 19 } 20 }
客户端
1 public class Client { 2 3 public static void main(String[] args) { 4 // 选择并创建需要使用的策略对象 5 MemberStrategy strategy = new AdvancedMemberStrategy(); 6 // 创建环境 7 Price price = new Price(strategy); 8 // 计算价格 9 double quote = price.quote(300); 10 System.out.println("图书的最终价格为:" + quote); 11 } 12 13 }
策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。策略算法是相同行为的不同实现。在运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象。把所有的具体策略实现类的共同公有方法封装到抽象类里面,将代码向继承等级结构的上方集中。
策略模式优点:
1 通过策略类的等级结构来管理算法族。
2 避免使用将采用哪个算法的选择与算法本身的实现混合在一起的多重条件(if-else if-else)语句。
策略模式缺点:
1 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2 由于策略模式把每个算法的具体实现都单独封装成类,针对不同的情况生成的对象就会变得很多。
参考资料
标签:相同 blank rate 多重 不同 log exti member lan
原文地址:http://www.cnblogs.com/WJQ2017/p/7629109.html