天天看点

设计模式的故事之四:命令模式

作者:Java编程世界

前三则故事:

  • 设计模式的故事之三:责任链模式
  • 《设计模式》之策略模式:省时省力的打造更灵活的系统!
  • 《设计模式》之观察者模式:让代码更优雅,系统更易扩展!

在一座繁华的城市里,有一个年轻有为的程序员叫做坤坤。他是一名Java开发工程师,擅长设计和开发高效的软件系统。每天,坤坤都会为自己的项目奋斗,努力提高自己的技能和能力。但是,他发现自己在处理一些复杂的业务逻辑时,总是遇到一些棘手的问题,而这些问题又经常会影响到整个系统的性能和稳定性。

为了解决这些问题,坤坤开始研究Java设计模式,并逐渐掌握了各种设计模式的优缺点和适用场景。在这些设计模式中,他最喜欢的就是命令模式。

命令模式是一种行为型设计模式,它可以将请求封装成一个对象,从而使不同的请求可以通过不同的命令对象来处理。这种模式的好处在于,它可以将请求的发送者和接收者解耦,从而更容易实现请求的撤销和重做等功能。

坤坤开始着手应用命令模式来优化他的项目。他先是定义了一个抽象的命令接口,然后根据不同的业务逻辑实现了不同的具体命令类。接着,他将命令对象和请求发送者进行绑定,使得每个命令对象都可以处理来自不同发送者的请求。最后,他将所有的命令对象都存放在一个命令调用者对象中,从而实现了请求发送者和请求接收者之间的解耦。

为了更好地理解命令模式的应用,坤坤决定写一个小例子。在这个例子中,他假设有一个遥控器,这个遥控器可以控制各种家电设备,比如电视机、音响、灯光等等。每个家电设备都有自己的开关命令,而遥控器上的按钮就代表不同的命令对象。这样一来,用户只需要按下相应的按钮,就可以控制不同的家电设备,而无需关心具体的实现细节。

坤坤开始动手编写代码。他先是定义了一个抽象的命令接口,其中包括了执行和撤销两个方法:

public interface Command {
    void execute();
    void undo();
}           

接着,他实现了具体的命令类,分别用于控制电视机、音响和灯光等设备的开关:

public class TVOnCommand implements Command {
    private TV tv;
    public TVOnCommand(TV tv) {
        this.tv = tv;
   }
public void execute() {
    tv.on();
}
public void undo() {
    tv.off();
}
}
public class TVOffCommand implements Command {
    private TV tv;
    public TVOffCommand(TV tv) {
        this.tv = tv;
    }
    public void execute() {
        tv.off();
    }
    public void undo() {
        tv.on();
    }
}

public class StereoOnCommand implements Command {
    private Stereo stereo;
    public StereoOnCommand(Stereo stereo) {
        this.stereo = stereo;
    }
    public void execute() {
        stereo.on();
    }
    public void undo() {
        stereo.off();
    }
}

public class StereoOffCommand implements Command {
    private Stereo stereo;
    public StereoOffCommand(Stereo stereo) {
        this.stereo = stereo;
    }
    public void execute() {
        stereo.off();
    }
    public void undo() {
        stereo.on();
    }
}

public class LightOnCommand implements Command {
    private Light light;
    public LightOnCommand(Light light) {
        this.light = light;
    }
    public void execute() {
        light.on();
    }
    public void undo() {
        light.off();
    }
}

public class LightOffCommand implements Command {
    private Light light;
    public LightOffCommand(Light light) {
        this.light = light;
    }
    public void execute() {
        light.off();
    }
    public void undo() {
        light.on();
    }
}           

然后,他定义了一个命令调用者类,这个类可以管理所有的命令对象,并根据用户的请求来调用相应的命令:

public class RemoteControl {

    private Command[] onCommands;
    private Command[] offCommands;
    private Command undoCommand;
  
    public RemoteControl() {
        onCommands = new Command[3];
        offCommands = new Command[3];
        for (int i = 0; i < 3; i++) {
            onCommands[i] = new NoCommand();
            offCommands[i] = new NoCommand();
        }
        undoCommand = new NoCommand();
    }

    public void setCommand(int slot, Command onCommand, Command offCommand) {

        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;

    }

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

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

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

然后,他定义了一个命令调用者类,这个类可以管理所有的命令对象,并根据用户的请求来调用相应的命令:

public class RemoteControl {
    private Command[] onCommands;
    private Command[] offCommands;
    private Command undoCommand;
    public RemoteControl() {
        onCommands = new Command[3];
        offCommands = new Command[3];
        for (int i = 0; i < 3; i++) {
            onCommands[i] = new NoCommand();
            offCommands[i] = new NoCommand();
        }
        undoCommand = new NoCommand();
    }
    public void setCommand(int slot, Command onCommand, Command offCommand) {
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }
    public void onButtonWasPushed(int slot) {
        onCommands[slot].execute();
        undoCommand = onCommands[slot];
    }
    public void offButtonWasPushed(int slot) {
        offCommands[slot].execute();
        undoCommand = offCommands[slot];
    }
    public void undoButtonWasPushed() {
        undoCommand.undo();
    }
}
           

最后,坤坤定义了一些具体的家电设备类,例如电视机、音响和灯光等等:

public class TV {
    public void on() {
        System.out.println("TV is on.");
    }
    public void off() {
        System.out.println("TV is off.");
    }
}

public class Stereo {
    public void on() {
        System.out.println("Stereo is on.");
    }
    public void off() {
        System.out.println("Stereo is off.");
    }
}

public class Light {
    public void on() {
        System.out.println("Light is on.");
    }
    public void off() {
        System.out.println("Light is off.");
    }
}           

现在,坤坤可以编写一个小测试程序,测试他的命令模式实现是否正确:

public class Test {
  public static void main(String[] args) {
    RemoteControl remoteControl = new RemoteControl();

    TV tv = new TV();
    Stereo stereo = new Stereo();
    Light light = new Light();

    TVOnCommand tvOnCommand = new TVOnCommand(tv);
    TVOffCommand tvOffCommand = new TVOffCommand(tv);
    StereoOnCommand stereoOnCommand = new StereoOnCommand(stereo);
    StereoOffCommand stereoOffCommand = new StereoOffCommand(stereo);
    LightOnCommand lightOnCommand = new LightOnCommand(light);
    LightOffCommand lightOffCommand = new LightOffCommand(light);

    remoteControl.setCommand(0, tvOnCommand, tvOffCommand);
    remoteControl.setCommand(1, stereoOnCommand, stereoOffCommand);
    remoteControl.setCommand(2, lightOnCommand, lightOffCommand);

    remoteControl.onButtonWasPushed(0);
    remoteControl.offButtonWasPushed(0);
    remoteControl.undoButtonWasPushed();

    remoteControl.onButtonWasPushed(1);
    remoteControl.offButtonWasPushed(1);
    remoteControl.undoButtonWasPushed();

    remoteControl.onButtonWasPushed(2);
    remoteControl.offButtonWasPushed(2);
    remoteControl.undoButtonWasPushed();
}
}           

输出结果:

设计模式的故事之四:命令模式

坤坤很高兴他成功地实现了一个命令模式的应用程序,并对Java设计模式有了更深入的理解。

坤坤感到,他现在不仅可以更好地设计和实现应用程序,而且可以在工作中更好地与团队合作,因为他能够更好地理解和解释团队成员的代码,并提出改进建议。

继续阅读