设计模式学习——命令模式

现在我们手里有一副遥控器,上面有分别控制着电视、电灯、电脑开关的按钮,当我们按下按钮的开或者关控制键时,这些电器就会做出相应的反应,即请求者(遥控器),向接受者(电器)发送命令,接受者根据收到的命令做出相应的反应,这就是典型的命令模式场景,它利用命令这个接口实现了请求者与接受者的解耦。


命令模式

定义:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化对象,命令模式也支持撤销的操作。

UML图

  • 请求者:发起命令的对象
  • 命令接口:定义了execute方法,具体功能实现交由子类完成
  • 具体命令:实现了不同的功能方法,并包含有一个接受者对象,使接受者对象执行同样的操作
  • 接收者:知道如何实施与执行一个请求相关的操作

例子

首先,让我们先来建立一个命令接口

package command;

/**
 * 命令接口
 */
public interface Command {
    void execute();
}

以控制电灯开关的命令为例,各实现电灯的开/关 接口

package command;

/**
 * 开电灯命令,实现了命令接口,并持有命令接受者变量
 */
public class LightOnCommand implements Command {
    //私有化命令的接受者
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.lightOn();
    }
}
package command;

public class LightOffCommand implements Command {
    //私有化命令的接受者
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.lightOff();
    }
}

命令实现类实现了命令接口,并持有命令的接受者,请求者调用命令时,命令会向接受者发起请求,这样请求者与接受者就实现了解耦。

最后来实现遥控器(invoker):

package command;

/**
 * 遥控器
 */
public class RemoteControl {
    Command[] onCommands = new Command[5];
    Command[] offCommands = new Command[5];

    public void setOnCommond(Command onCommond,int i) {
        onCommands[i] = onCommond;
    }

    public void setOffCommand(Command offCommand,int i) {
        offCommands[i] = offCommand;
    }
    
    public void onButtonExcute(int i){
        onCommands[i].execute();
    }
    
    public void offButtonExcute(int i){
        offCommands[i].execute();
    }
}

这样,我们就可以调用遥控器的开关来控制相应电器的行为了,也可以设置遥控器的开关的种类。


小结

适用场景

  • 命令的发送者和命令的接受者有不同的生命周期,命令发送了不是马上执行
  • 命令有不同的管理逻辑
  • 需要支持撤销/重做命令

所以,命令模式是对功能方法的抽象,而不是对对象的抽象,它将功能方法提升到对象角度来操作,便于我们实现解耦。


源码在这里:我的github地址


猜你喜欢

转载自blog.csdn.net/lpckr94/article/details/81174613
今日推荐