设计模式(二)学习----策略模式

  •  策略设计模式:定义一组算法,将每个算法都分装起来,并使他们之间可以互换。 策略模式就是使用的面向对象思想中的继承和多态的机制

策略模式的通用类图:

  1. Context类:Strategy类,并且和Strategy类是整体和个体的关系,即聚合关系。对策略角色个体进行封装。
  2. Strategy接口:定义这个策略或算法必须有的方法和属性。
  3. 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();
    }

}

策略模式的优点:

  1. 算法可以自由切换:通过Context类对策略成员进行封装,保证对外提供"可自由切换”的策略。
  2. 避免使用多重条件判断,
  3. 扩展性良好

策略模式的缺点:

  1. 策略类数量太多:每一个策略都是一个类,复用性很小,类数量增多。
  2. 所有策略类都需要向外暴露:客户端必须知道有哪些策略才能决定使用哪一个策略。导致封装类没有意义,可以使用工厂模式解决。

应用:

我们假设有如下场景:

      我们使用聊天工具聊天时,可以发送点对点消息(私聊)和点对多消息(群聊),而发送不同的消息执行的操作是不一样的,也就是说我们在不同的场景下(私聊或者 群聊)发送消息时会调用不同的发送方法,但是我们只有一个消息发送器(可以理解为发送消息时的发送按钮),我们希望可以通过这消息发送器发送任何类型的消 息。

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();
    }

}
原文地址:https://www.cnblogs.com/200911/p/3907054.html