【设计模式】23种设计模式之命令模式

命令模式

定义

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

个人理解:命令模式简单来说就是将命令/请求以Java对象的形式进行封装,通过对象间的调用将命令对象进行传递,直到命令接收方,然后命令接收方通过调用命令对象的方法执行命令。

UML类图

【设计模式】23种设计模式之命令模式_第1张图片

使用场景

认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令; 2、模拟 CMD。

实例

抽象命令接口

/**
 * @Desc 命令接口
 * @Author snmeng
 * @Date 2022/8/20 16:36
 * @Version 1.0
 */
public interface Command {
    // 执行
    void execute();

    // 撤销
    void revoke();
}

无命令类:实现命令接口

/**
 * @Desc 无命令类(避免null的情况)
 * @Author snmeng
 * @Date 2022/8/20 19:39
 * @Version 1.0
 */
public class NoCommand implements Command{

    @Override
    public void execute() {

    }

    @Override
    public void revoke() {

    }
}

电灯关闭命令类:实现命令接口

/**
 * @Desc 电灯关闭命令类
 * @Author snmeng
 * @Date 2022/8/20 19:56
 * @Version 1.0
 */
public class LightOffCommand implements Command {
    Light light; // 电灯实例

    // 创建电灯关闭命令类实例时。需初始化具体电灯实例
    public LightOffCommand(Light light) {
        this.light = light;
    }

    // 执行关闭命令
    @Override
    public void execute() {
        light.off();
    }

    // 执行撤销命令
    @Override
    public void revoke() {
        light.on();
    }
}

电灯开启命令类:实现命令接口

/**
 * @Desc 电灯开启的命令类
 * @Author snmeng
 * @Date 2022/8/20 19:53
 * @Version 1.0
 */
public class LightOnCommand implements Command {
    Light light; // 电灯实例

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

    // 执行开启命令
    @Override
    public void execute() {
        light.on();
    }

    // 执行撤销命令
    @Override
    public void revoke() {
        light.off();
    }
}

控制器: 用于保存一组命令,根据命令调用方的请求执行不同的命令

/**
 * @Desc 控制器
 * @Author snmeng
 * @Date 2022/8/20 19:32
 * @Version 1.0
 */
public class Controller {
    private Command[] onCommands; // 开启命令
    private Command[] offCommands; // 关闭命令
    private Command revokeCommand; // 撤销命令

    // 控制器一开始需要初始化命令队列,将命令队列的on命令和off命令都设置成NoCommand实例
    public Controller() {
        onCommands = new Command[7];
        offCommands = new Command[7];
        NoCommand noCommand = new NoCommand();
        for (int i = 0; i < 7; i++) {
            onCommands[i] = noCommand;
            offCommands[i] = noCommand;
        }
        // 一开始撤销命令也是空的
        revokeCommand = noCommand;
    }

    // 给控制器指定位置的按键设置命令
    public void setCommand(int index, Command onCommand, Command offCommand) {
        onCommands[index] = onCommand;
        offCommands[index] = offCommand;
    }

    // 按下指定位置的On按键后执行
    public void onButtonWasPressed(int index) {
        onCommands[index].execute();
        // 记录当前命令
        revokeCommand = onCommands[index];
    }

    // 按下指定位置的Off按键后执行
    public void offButtonWasPressed(int index) {
        offCommands[index].execute();
        // 记录当前命令
        revokeCommand = offCommands[index];
    }

    // 撤销按钮被按下后执行撤销命令
    public void revokeButtonWasPressed() {
        // 使用当前命令调用其撤销方法
        revokeCommand.revoke();
    }
}

优缺点

优点:

1.降低了系统耦合度

2.新的命令可以很容易添加到系统中去

缺点:

使用命令模式可能会导致某些系统有过多的具体命令类

注意事项: 使用命令模式的系统一般需要支持命令的撤销(Undo)操作和恢复(Redo)操作

工作中的应用

敬请期待

设计原则工具箱

1.找出应用中可能需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混合在一起

2.针对接口(超类型)编程而不是针对具体的实现编程

3.多用组合少用继承

4.为了交互对象之间的松耦合设计而努力

5.类应该对扩展开放,对修改关闭

6.依赖抽象,不要依赖具体类。(即不要让高层组件依赖低层组件,而且不管高层组件还是低层组件都应该依赖于抽象)

你可能感兴趣的:(java,命令模式,设计模式,java)