zoukankan      html  css  js  c++  java
  • [设计模式] javascript 之 命令模式

    模式定义:

    [定义]: 将一个请求封装成一个对象,使得你用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。

      组成: 调用者(Invoker),命令请求(Command,包括接口或抽象,以及实现,待对象化),接收者(实现者 Receiver,包括抽象接口,及实现),三个角色;

      过程: 命令通过请求者发送给接收者来实现; 命令委托间接通知,再执行实现;

      理解: 请求可能会有多个,接收者可能也有多个,可能一个请求一个执行者,也可能多个请求一个执行者; 请求以及执行者是耦合的,客户端可以调用时,可以给请求指定个执行者,以及执行方法; 这个就可以达到请求参数化的效果,并可以对请求进行排队列等等操作;

     因此它可以通过以下方式来表达 请求者与接收者 的耦合,以及请求者通过发送命令,不必具体知识执行了什么的效果;

    var invoker = new Invoker(concreteCommand1);
    invoker.execute();
    invoker = new Invoker(concreteCommand2);
    invoker.execute();

     或者:

    var invoker = new Invoker();
    invoker.setCommand(concreteCommand1);
    invoker.execute();
    var invoker2 = ....

    以上的语句特点:

    1. 一个请求只执行一个操作,每个操作都伴随一个具体的命令实现类;
    2. 因为具体的执行操作是在具体的接收着进行的,请求通过执行命令类才能执行到,因此它又具有委托(callback)的特点;

    这样设计的优缺点:

     这里要说到两个设计原则:开闭原则,以及依赖倒置原则;

     开闭原则:就是对扩展是开放的,对于修改是关闭的;它是面向对象里最重新的原则之一,是提高代码可复用的原则;

          现实世界中,存在在众多行为操作类似的事物,比如不一样的人,都拥有吃饭,看书,运动的能力;

          但每个人表现出来的行为动作可能,喜好可能是是不一样;但我们将每个人各种动作(方法)整合在一个大类里实现时,

          第一会出现很多类似重复的方法,第二整个类会很大,很杂,不好维护;当仅是其中一个的喜好出现不一样时,修改可能还会影响到其他人的操作;

          因此在面向对象的思想里,推荐对每个类基于抽象进行编程,不管是继承抽象,或是实现接口;这样出现需对新的类似事物进行扩展时,只需基于抽象进行扩展;

     依赖倒置原则:

                         1. 抽象不能依束于具体实现,具体实现要依赖于抽象; 简单就是编程要针对抽象或接口编程,不要针对具体实现编辑;

          2. 开闭原则是整个面向对象编辑的基础,也是终级目标;依赖倒置原则是实现开闭原则的一个基础;

          3. 想对于具体实现,抽象或接口会比较稳定,针对接口或抽象进行编辑,提高开发的稳定性,不会由具体实现因为具体情况的多变不稳定性,而可能需要经常修改;

              针对稳定的抽象进行编辑,多变的具体实现针对抽象实现,提高内聚低耦合的效果,具体独立,才可以更好的针对变化进行扩展,而不是修改;

    应用场景:

     a. 比如老板让员工执行某项任务; (老板: Invoker,员工: Receiver,请求命令:command)

      老板可以随便指定一个员工(员工多个),员工实现手段不一样,老板不必知道;

      请求命令,工作任务也有很多种...  (每个任务,也都各自的实现手段跟组成,多个方法)

    b. 比如 通过摇控机控制多种设备的开机关机等; (手是Invoker,按钮是Receiver, 命令是设备的开关机)

      摇控机上多组按钮组合(电灯的开跟关,电视机,以及电风扇的)

      手可以点击任意一个按钮;

      命令这里就是开或关;

    源码实现:

    //接收者
    function Worker() {
    }
    Worker.prototype.doMethod = function() {
        //do somethong;
    }
    
    //命令
    functiom Command(worker) {
        this.worker = worker;
    }
    
    Command.prototype.doCommand = function() {
       // do command
       this.worker.doMethod();
    }
    
    //调用者
    function Invoker(command) {
        this.doWork = function() {
             command.doCommand
        }
    }
    
    /////////////////////////////////////////////////////////
    
    //客户端调用(工作具体工作实现)
    var workerA = new Worker();
    
    var commandA = new Command(workerA);
    
    var invoker = new Invoker(commandA);
    invoker.doWork();

     换成JAVA的写法,即Worker一个接口或抽象类,两个具体的工人类(Worker实现),Command为接口或抽象,一两个具体的实现;

    调用处,针对接口或抽象进行调用具体的请求以及接收者,调用者Invoker再执行相应的方法;

  • 相关阅读:
    丑数——剑指offer面试题34
    把整数排成最小的数——剑指offer面试题33
    从1到n整数中1出现的次数——剑指offer面试题32
    各种排序方法及其比较
    scrapy安装
    水仙花数
    分数化小数(decimal)
    子序列的和
    倒三角
    韩信点兵
  • 原文地址:https://www.cnblogs.com/editor/p/6027633.html
Copyright © 2011-2022 走看看