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

      在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)。

    模式结构:

      1.Command接口:抽象命令,它会定义一个命令对象应具备的一系列命令操作,比如excute()、undo()、redo()等;

      2.ConcreteCommand(命令接口实现对象):具体的命令实现类,这里它会绑定命令操作与接收者之间的关系,如excute()命令的实现委托给Receiver的某个函数;

      3.Receiver(接收者):真正执行命令的对象(真实命令执行者),它知道如何处理具体的业务逻辑;

      4.Invoker:要求命令对象执行请求,持有命令接口实现对象(命令对象),可以持有多个命令对象,这个是客户端触发命令并要求命令执行相应操作的地方,也就是说相当于          使用命令对象的入口。

      5.Client:创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。

      理解:调用者Invoker与操作者Receiver通过Command命令接口实现解耦。对于调用者来说,我们可以注入多个命令操作,比如新建文件、复制文件、删除文件这样三个操作,调用者只需在需要的时候直接调用即可,而不需要知道这些操作命令是如何实现的。

    那么,看完一个例子就更明白什么是命令模式了以及如何实现命令模式。

    public interface Command {
        public void execute();
        public void undo();
    }
    public class LightOnCommand implements Command{
        private Light light;
        public LightOnCommand(Light light){
            this.light = light;
        }
        @Override
        public void execute() {
            light.on();
        }
        @Override
        public void undo() {
            light.off();
        }
    }
    public class Light {
        private String name;
        public Light(String name) {
            this.name = name;
        }
        public Light(){
        }
        public void on() {
            System.out.println(name+" Light is on!");
        }
        public void off() {
            System.out.println(name+" Light is off!");
        }
    }
    public class SimpleRemoteControl {
        private Command slot;
        public SimpleRemoteControl(){
        }
        public void setCommand(Command command){
            slot = command;
        }
        public void buttonWasPressed(){
            slot.execute();
        }
    }
    import com.wp.design.command.bean.GarageDoor;
    import com.wp.design.command.bean.Light;
    import com.wp.design.command.impl.GarageDoorOpenCommand;
    import com.wp.design.command.impl.LightOnCommand;
    public class RemoteControlTest {
        public static void main(String[] args) {
            SimpleRemoteControl remote = new SimpleRemoteControl();
            Light light = new Light();
            GarageDoor garageDoor = new GarageDoor();
            LightOnCommand lightOn = new LightOnCommand(light);
            GarageDoorOpenCommand garageDoorOpen = new GarageDoorOpenCommand(garageDoor);
            remote.setCommand(lightOn);
            remote.buttonWasPressed();
            remote.setCommand(garageDoorOpen);
            remote.buttonWasPressed();
        }
    }

    这是一个遥控器,遥控器上面有开和关按钮,SimpleRemoteControl视为遥控器类,属于结构中的Invoker,持有命令对象的引用,buttonWasPressed()方法表示按钮按下,执行命令对象的execute()方法。

    RemoteControlTest属于结构中的Client,创建LightOnCommand电灯打开的命令对象,并设置电灯对象为Receiver接收者,然后将该命令对象绑定到遥控器按钮上,当按钮按下后,电灯便打开了。真正执行命令的是电灯对象。命令请求者则是遥控器对象。可以很明显的看出行为请求者和行为执行者解耦,便于系统的更新和升级。

  • 相关阅读:
    net core 使用 rabbitmq
    asp.net core WebApi 返回 HttpResponseMessage
    asp.net core 2.1 WebApi 快速入门
    JQuery EasyUI combobox动态添加option
    php截取字符去掉最后一个字符
    JQuery EasyUI Combobox的onChange事件
    对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成
    Access2007 操作或事件已被禁用模式阻止解决办法
    Easyui 中 Tabsr的常用方法
    Win 7 IE11不能下载文件,右键另存为也不行
  • 原文地址:https://www.cnblogs.com/zhanxiaoyun/p/6323438.html
Copyright © 2011-2022 走看看