zoukankan      html  css  js  c++  java
  • 命令模式

    行为型:Command(命令模式)

      命令模式:

     

      目的:其实一般设计模式就是为了解耦。也没什么特别的,命令模式实际上就是将命令的请求者和命令的执行者解耦。

      白话:领导说了,让把这个月的项目计划压缩到三个礼拜完成,还说了:"不管你用什么办法"。这句“不管你用什么办法”就是我们所说的解耦。我不需要关心你怎么去做,我只要你能实现我想达到的目的。

     

      模式结构:一般包含下面几个部分。

        Client:客户

        Invoker:命令触发者

        Command:命令

        ConcreteCommand:具体命令实现

        Receiver:命令执行者(接收者)

      还是按生活场景来做比喻,现在我们(Client)来到了一家餐厅,服务员(Invoker)帮我们下了一个订单(ConcreteCommand),交给了厨师(Receiver)。用订单来传递信息的话,服务员和厨师都不需要互相了解和沟通。

      这是Head First设计模式中的举例,其实生活中还有很多的场景会用到命令模式。但我想,没有什么会比领导跟你说不管你用什么办法,必须在这个星期内完成任务,这样的情况更让你感到深刻了。

      下面我们用一个电视遥控器的Demo来演示:

      

    package top.gabin.oa.web.design.command;
    
    /**
     * 命令接口
     * @author linjiabin on  16/5/2
     */
    public interface Command {
        /**
         * 执行命令
         */
        void execute();
    
        /**
         * 撤销命令
         */
        void undo();
    }
    package top.gabin.oa.web.design.command;
    
    /**
     * 电视接口
     * @author linjiabin on  16/5/2
     */
    public interface TV {
        void powerOn();
        void powerOff();
    }
    package top.gabin.oa.web.design.command;
    
    /**
     * 电源开关
     * @author linjiabin on  16/5/2
     */
    public class PowerCommand implements Command{
        private TV tv;
    
        public PowerCommand(TV tv) {
            this.tv = tv;
        }
    
        @Override
        public void execute() {
            tv.powerOn();
        }
    
        @Override
        public void undo() {
            tv.powerOff();
        }
    }
    package top.gabin.oa.web.design.command;
    
    /**
     * 乐视TV
     * @author linjiabin on  16/5/2
     */
    public class LeshiTv implements TV {
        @Override
        public void powerOn() {
            System.out.println("打开电视");
        }
    
        @Override
        public void powerOff() {
            System.out.println("关掉电视");
        }
    }
    package top.gabin.oa.web.design.command;
    
    /**
     * 遥控器
     * @author linjiabin on  16/5/2
     */
    public class RemoteControl {
        // 最简单的单例模式
        private static TV tv = new LeshiTv();
    
        public void powerButtonOn() {
            PowerCommand powerCommand = new PowerCommand(tv);
            powerCommand.execute();
        }
    
        public void powerButtonOff() {
            PowerCommand powerCommand = new PowerCommand(tv);
            powerCommand.undo();
        }
    
    }
    /**
     * 命令测试类
     * @author linjiabin on  16/5/2
     */
    public class TestCommand {
    
        @Test
        public void testCommand() {
            RemoteControl remoteControl = new RemoteControl();
            remoteControl.powerButtonOn();
            remoteControl.powerButtonOff();
        }
    
    }

    输出:

    打开电视
    关掉电视

      上述的Demo,主要是分离了电视厂商的功能实现和遥控器按钮点击对应的命令。就如同我们匹配了电视和遥控器,这时候遥控器持有一个电视厂商的实现,在我们点击任意遥控器按钮的同时,遥控器会将持有的电视厂商传递给命令对象,而由命令对象去操作实际电视厂商的接口。

      好处很明显,电视厂商不需要再关注遥控器的按钮是如何分布的,按下之后该执行什么操作。反正电视厂商只提供具体功能的接口,遥控器只管生成对应的命令,并将实际命令的执行者:电视厂商传递进去即可。

      这看上去似乎没什么了不起的?但你别忘了,你随时都会适配一个新的电视厂商的实现,你确定你想要让所有的遥控器按钮都绑定到一个厂商实现吗?

      不知道此时的你是否会有一种感触:哦天,要是我的老板也懂得命令模式,我是不是再也不用跟他解释我昨天是如何搞定客户的(那一些细到我请了客户吃过几次饭,都点什么菜的细节?)

  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/gabin/p/5453410.html
Copyright © 2011-2022 走看看