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

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

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

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

  • 相关阅读:
    Laravel5如何向闭合函数内传递参数 where function 传参
    laraveladmin省市区三级联动
    laravel中间件失效,配置文件重新加载
    Laravel-admin 加载视图后,blade 模板 JS 失效
    laravel-admin Field type [editor] does not exist.
    laravel-admin 表单提交报错
    laravel-admin利用ModelTree实现对分类信息的管理
    laravel-admin后台框架基本使用
    C#模版学习研究
    github下载下来的C#控制台小游戏[含源码]
  • 原文地址:https://www.cnblogs.com/gabin/p/5453410.html
Copyright © 2011-2022 走看看