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

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

策略模式的通用类图:

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

    }



}

 

你可能感兴趣的:(设计模式)