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

    命令模式

    命令模式Command Pattern是一种数据驱动的设计模式,其属于行为型模式,别名为动作Action模式或事务Transaction模式,命令模式将请求以命令的形式包裹在对象中,并传给调用对象,调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象对请求排队或者记录请求日志,以及支持可撤销的操作。

    描述

    在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。命令模式也可以用于实现基于事务的系统,一旦执行命令,便会继续保留命令的历史记录,如果最终命令成功执行,那么一切都很好,否则只需遍历历史记录并继续对所有已执行的命令执行撤消即可。

    优点

    • 降低系统的耦合度。
    • 新的命令可以很容易地加入到系统中。
    • 可以比较容易地设计一个命令队列和宏命令(组合命令)。
    • 可以方便地实现对请求的Undo和Redo。

    缺点

    • 使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

    适用环境

    • 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
    • 系统需要在不同的时间指定请求、将请求排队和执行请求。
    • 系统需要支持命令的撤销Undo操作和恢复Redo操作。
    • 系统需要将一组操作组合在一起,即支持宏命令

    实现

    // 假设我们有一个电灯,我们使用遥控器对其进行控制
    
    class Bulb {
        turnOn() {
            console.log("Bulb has been lit!");
        }
        
        turnOff() {
            console.log("Darkness!");
        }
    }
    
    class Command {
        execute(){
            throw new Error("Abstract method cannot be called");
        }
    
        redo(){
            throw new Error("Abstract method cannot be called");
        }
    
        undo(){
            throw new Error("Abstract method cannot be called");
        }
    }
    
    class TurnOnCommand extends Command{
        constructor(bulb) {
            super();
            this.bulb = bulb;
        }
        
        execute() {
            this.bulb.turnOn();
        }
        
        undo() {
            this.bulb.turnOff();
        }
        
        redo() {
            this.execute();
        }
    }
    
    class TurnOffCommand extends Command {
        constructor(bulb) {
            super();
            this.bulb = bulb;
        }
        
        execute() {
            this.bulb.turnOff();
        }
        
        undo() {
            this.bulb.turnOn();
        }
        
        redo() {
            this.execute();
        }
    }
    
    class RemoteControl {
        submit(command) {
            command.execute();
        }
    }
    
    (function(){
        var bulb = new Bulb();
    
        var turnOn = new TurnOnCommand(bulb);
        var turnOff = new TurnOffCommand(bulb);
    
        var remote = new RemoteControl();
        remote.submit(turnOn); // Bulb has been lit!
        remote.submit(turnOff); // Darkness!
    })();
    

    每日一题

    https://github.com/WindrunnerMax/EveryDay
    

    参考

    https://www.runoob.com/design-pattern/command-pattern.html
    https://github.com/sohamkamani/javascript-design-patterns-for-humans#-command
    https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/command.html
    
  • 相关阅读:
    Advanced Configuration Tricks
    Reviewing the Blog Module
    Editing and Deleting Data
    Making Use of Forms and Fieldsets
    Understanding the Router
    SQL Abstraction and Object Hydration
    Preparing for Different Databases
    Java学习理解路线图
    Openstack学习历程_1_视频
    CentOS安装Nginx负载
  • 原文地址:https://www.cnblogs.com/WindrunnerMax/p/13897236.html
Copyright © 2011-2022 走看看