设计模式之strategy策略模式
1.意图
Strategy模式不只是封装一系列可以互相提华纳的算法逻辑,使得具体的算法的演化独立于使用它们的客户端代码,而且我们不应该只着眼“算法”一词。实际上,只要能够有效地剥离客户端代码与特定关注点之间的依赖关系,Strategy模式都应该进入考虑之列。只要针对同一件事情有多种选择的时候,都可以考虑用Strategy模式来统一一下抽象接口。
2.类图

其中一个Composition类负责维护和更新一个正文浏览程序中显示的正文换行。换行策略不是Composition类实现的,而是由抽象的Compositor类的子类各自独立地实现的。
Compositor各个子类实现不同的换行策略:
- SimpleCompositor 实现一次确定一个换行位置
- TeXCompositor 实现一次处理一段文字的换行
- ArrayCompositor 实现每一行都含有一个固定数目的项,用于对一系列图标进行分行。
Composition维护队Compositor对象的一个引用。一旦Composition重新格式化它的正文,他就将这个职责发给它的Compositor对象。Composition的客户指定应该使用那一种 Compositor的方式是直接将它想要的Compositor装入Composition中。
3.适用性
(1)许多相关的类仅仅是行为有异。
(2)使用一个算法的不同变体。
(3)算法使用客户不应该知道的数据。
(4)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
5.结构

6 参与者
Strategy(策略,如Compositor)- 定义所有支持的算法的公共接口。Context使用这个接口调用某个具体的ConcreteStrategy定义的算法。
ConcreteStrategy(具体策略,如SimpleCompositor,TeXCompositor,ArrayCompositor)- 以Strategy接口实现某具体算法。
Context(上下文,如Composition)
- 用一个ConcreteStrategy对象来配置。
- 维护一个对Strategy对象的引用。
- 可定义一个接口来让Strategy访问它的数据。
7 协作
- Strategy和Context相互作用以实现选定的算法。
- Context将它的客户请求转发给它的Strategy。客户通常创建并传递一个ConcreteStrategy对象给该Context;客户仅与Context交互。通常有一系列的ConcreteStrategy类可供客户从中选择。
8 实现
//抽象算法接口:定义了所有支持算法的公共接口 public interface Strategy { //算法方法:打印商品的价格(不同的实现打不同的折扣) public double getPrice(double price); }
//具体的算法:普通用户,不打折 public class GeneralUser implements Strategy { @Override public double getPrice(double price) { System.out.println("普通用户,不打折"); return price; } } //具体的算法:注册用户:打9折 public class RegisterUser implements Strategy{ @Override public double getPrice(double price) { System.out.println("注册用户:打9折"); return price*0.9; } } //具体的算法:普通会员:打8折 public class RegisterVip implements Strategy{ @Override public double getPrice(double price) { System.out.println("普通会员:打8折"); return price*0.8; } } //具体的算法:老会员:打5折 public class OldVip implements Strategy{ @Override public double getPrice(double price) { System.out.println("老会员:打5折"); return price*0.5; } }
//上下文:用来维护不同对象的不同折扣 public class Context { private Strategy strategy;//持有算法族的引用 public Context(Strategy strategy) { super(); this.strategy = strategy; } //打印价钱 public void printPrice(double price){ System.out.println("应付金额:"+Math.round(strategy.getPrice(price))); } }
public static void main(String[] args) { double price = 998;//商品价格 Strategy generalUser = new GeneralUser();//普通用户 Strategy registerUser = new RegisterUser();//注册用户 Strategy registerVip = new RegisterVip();//普通会员 Strategy oldVip = new OldVip();//老会员 //根据不同的用户打不同的折扣 Context c1 = new Context(generalUser); c1.printPrice(price); Context c2 = new Context(registerUser); c2.printPrice(price); Context c3 = new Context(registerVip); c3.printPrice(price); Context c4 = new Context(oldVip); c4.printPrice(price); }
浙公网安备 33010602011771号