设计模式-命令模式

2023-05-04 15:04:26 浏览数 (1)

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成一个对象,从而允许使用不同的请求、队列或者日志来参数化其他对象。命令模式支持撤销操作,它的核心思想就是将一个请求封装为一个对象,然后通过不同的命令对象来执行请求。

命令模式主要包含以下几个角色:

  1. Command(抽象命令):定义一个命令的接口,声明执行命令的方法。
  2. ConcreteCommand(具体命令):实现抽象命令接口,具体定义一个命令。
  3. Invoker(调用者):要求该命令执行这个请求。
  4. Receiver(接收者):知道如何实施与执行一个请求相关的操作。

下面是一个简单的命令模式的 Java 示例,该示例模拟一个遥控器,遥控器有四个按键分别对应不同的电器,可以控制电器的开关,以及撤销上一步操作。

代码语言:javascript复制
// 命令接口
interface Command {
    void execute();
    void undo();
}

// 具体命令-打开电灯
class LightOnCommand implements Command {
    private Light light;

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

    public void execute() {
        light.on();
    }

    public void undo() {
        light.off();
    }
}

// 具体命令-关闭电灯
class LightOffCommand implements Command {
    private Light light;

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

    public void execute() {
        light.off();
    }

    public void undo() {
        light.on();
    }
}

// 具体命令-打开电视
class TvOnCommand implements Command {
    private Tv tv;

    public TvOnCommand(Tv tv) {
        this.tv = tv;
    }

    public void execute() {
        tv.on();
    }

    public void undo() {
        tv.off();
    }
}

// 具体命令-关闭电视
class TvOffCommand implements Command {
    private Tv tv;

    public TvOffCommand(Tv tv) {
        this.tv = tv;
    }

    public void execute() {
        tv.off();
    }

    public void undo() {
        tv.on();
    }
}

// 电灯类
class Light {
    public void on() {
        System.out.println("电灯已打开");
    }

    public void off() {
        System.out.println("电灯已关闭");
    }
}

// 电视类
class Tv {
    public void on() {
        System.out.println("电视已打开");
    }

    public void off() {
        System.out.println("电视已关闭");
    }
}

// 遥控器类
class RemoteControl {
    private Command[] onCommands;
    private Command[] offCommands;
    private Command undoCommand;

    public RemoteControl() {
        onCommands = new Command[4];
        offCommands = new Command[4];

        for (int i = 0; i < 4; i  ) {
            onCommands[i] = () -> {};
            offCommands[i] = () -> {};
        }

        undoCommand = () -> {};
    }

    public void setCommand(int slot, Command onCommand, Command offCommand) {
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }

    public void onButtonPressed(int slot) {
        onCommands[slot].execute();
        undoCommand = onCommands[slot];
    }

    public void offButtonPressed(int slot) {
        offCommands[slot].execute();
        undoCommand = offCommands[slot];
    }

    public void undoButtonPressed() {
        undoCommand.undo();
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        RemoteControl remoteControl = new RemoteControl();

        Light livingRoomLight = new Light();
        Light kitchenLight = new Light();
        Tv livingRoomTv = new Tv();

        LightOnCommand livingRoomLightOnCommand = new LightOnCommand(livingRoomLight);
        LightOffCommand livingRoomLightOffCommand = new LightOffCommand(livingRoomLight);
        LightOnCommand kitchenLightOnCommand = new LightOnCommand(kitchenLight);
        LightOffCommand kitchenLightOffCommand = new LightOffCommand(kitchenLight);
        TvOnCommand livingRoomTvOnCommand = new TvOnCommand(livingRoomTv);
        TvOffCommand livingRoomTvOffCommand = new TvOffCommand(livingRoomTv);

        remoteControl.setCommand(0, livingRoomLightOnCommand, livingRoomLightOffCommand);
        remoteControl.setCommand(1, kitchenLightOnCommand, kitchenLightOffCommand);
        remoteControl.setCommand(2, livingRoomTvOnCommand, livingRoomTvOffCommand);

        remoteControl.onButtonPressed(0);
        remoteControl.offButtonPressed(0);
        remoteControl.onButtonPressed(1);
        remoteControl.undoButtonPressed();
        remoteControl.offButtonPressed(1);
        remoteControl.onButtonPressed(2);
        remoteControl.offButtonPressed(2);
    }
}

在上面的示例代码中,遥控器类 RemoteControl 包含了四个按键,分别对应不同的电器。遥控器类中有一个 setCommand 方法,用于设置不同的命令,通过 onButtonPressedoffButtonPressed 方法,分别执行开启和关闭操作。同时,遥控器类还有一个 undoButtonPressed 方法,用于撤销上一步操作。

可以看到,命令模式非常适用于需要支持撤销操作的场景。在该示例中,我们可以通过遥控器来开启和关闭不同的电器,并且可以撤销上一步操作。这样做的好处是,我们可以在不知道电器具体实现的情况下,使用遥控器进行控制,而不必关心每个电器的具体实现方式。

0 人点赞