zoukankan      html  css  js  c++  java
  • 设计模式(二)学习----策略模式

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

    策略模式的通用类图:

    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();
        }
    
    }
  • 相关阅读:
    调用Win32 API netapi32.dll 实现UNC(网络共享)连接的管理(一)
    一个重写Page基类的例子
    36进制进位算法例子
    关于.net 中调用script的alert后 css失效的办法
    Javascript:keyCode键码值表
    Url地址重写,利用HttpHander手工编译页面并按需生成静态HTML文件
    在.NET程序中正确使用String类型
    Sql Server中自动序号的方法
    托管和非托管的关系和区别
    Oracle 格式化
  • 原文地址:https://www.cnblogs.com/200911/p/3907054.html
Copyright © 2011-2022 走看看