- 策略设计模式:定义一组算法,将每个算法都分装起来,并使他们之间可以互换。 策略模式就是使用的面向对象思想中的继承和多态的机制
策略模式的通用类图:
- Context类:Strategy类,并且和Strategy类是整体和个体的关系,即聚合关系。对策略角色个体进行封装。
- Strategy接口:定义这个策略或算法必须有的方法和属性。
- ConcreteStrategy1,ConcreteStrategy2具体策略角色实现类。实现抽象策略中的方法,该类中含有具体的算法。
上图变成Java代码:
抽象的策略角色:
package com.lp.ecjtu.strategy1; public interface Strategy { /** * 策略模式的运算法则,抽象的策略角色 */ public void doSomething(); }
具体的策略角色:
package com.lp.ecjtu.strategy1; public class ConcreteStrategy1 implements Strategy { @Override public void doSomething() { System.out.println("具体策略1的运算法则"); } } package com.lp.ecjtu.strategy1; public class ConcreteStrategy2 implements Strategy { @Override public void doSomething() { System.out.println("具体策略2的运算法则"); } }
封装角色:
package com.lp.ecjtu.strategy1; public class Context { //抽象策略,与Strategy接口是聚合关系 private Strategy strategy; //构造函数设置具体策略 public Context(Strategy conStrategy){ this.strategy = conStrategy; } //封装后的策略方法 public void doAnyThing(){ this.strategy.doSomething(); } }
高层模块:
package com.lp.ecjtu.strategy1; public class Client { /** * @param args */ public static void main(String[] args) { //声明一个具体的策略,父类的引用指向子类,使用多态 Strategy strategy = new ConcreteStrategy1(); Context context = new Context(strategy); context.doAnyThing(); Strategy strategy2 = new ConcreteStrategy2(); Context context2 = new Context(strategy2); context2.doAnyThing(); } }
策略模式的优点:
- 算法可以自由切换:通过Context类对策略成员进行封装,保证对外提供"可自由切换”的策略。
- 避免使用多重条件判断,
- 扩展性良好
策略模式的缺点:
- 策略类数量太多:每一个策略都是一个类,复用性很小,类数量增多。
- 所有策略类都需要向外暴露:客户端必须知道有哪些策略才能决定使用哪一个策略。导致封装类没有意义,可以使用工厂模式解决。
应用:
我们假设有如下场景:
我们使用聊天工具聊天时,可以发送点对点消息(私聊)和点对多消息(群聊),而发送不同的消息执行的操作是不一样的,也就是说我们在不同的场景下(私聊或者 群聊)发送消息时会调用不同的发送方法,但是我们只有一个消息发送器(可以理解为发送消息时的发送按钮),我们希望可以通过这消息发送器发送任何类型的消 息。
java代码:
package com.lp.ecjtu.strategy; public interface IMessage { /** * ClassName:IMessage * Function: 这是一个消息的接口,所有的消息都要实现这个接口. * Reason: TODO ADD REASON. * Date: 2014-8-12 上午11:33 * @author lipeng * @version * @since JDK 1.6 * @see */ public void send(); }
package com.lp.ecjtu.strategy; public class P2MMsg implements IMessage { @Override public void send() { // TODO Auto-generated method stub System.out.println("这是点对多的消息,将发送给多个人"); } } package com.lp.ecjtu.strategy; public class P2PMessage implements IMessage { @Override public void send() { // TODO Auto-generated method stub System.out.println("这是点对多的消息,将发送给一个人"); } }
package com.lp.ecjtu.strategy; /** * 封装角色 * @author Administrator * */ public class MessageSender { //抽象策略,要使用的消息 private IMessage message;//与IMessage是聚合关系 //构造函数设置具体策略,你要使用哪种消息 public MessageSender(IMessage message){ this.message = message; } public void send(){ this.message.send(); } }
package com.lp.ecjtu.strategy; /** * 策略设计模式:定义一组算法,将每个算法都分装起来,并使他们之间可以互换。 * 策略模式就是使用的面向对象思想中的继承和多态的机制。 * * * @author Administrator * */ public class UserClient { /** * 依次发送一条点对点的消息,和点对多的消息。 */ public static void main(String[] args) { //建立发送器 MessageSender msgSender; System.out.println("发送一条点对点的消息:"); msgSender = new MessageSender(new P2PMessage()); msgSender.send(); System.out.println("发送一条点对多的消息:"); msgSender = new MessageSender(new P2MMsg()); msgSender.send(); } }