行为型:命令模式

目录

1、核心思想

2、实现方式

[2.1 模式结构](#2.1 模式结构)

[2.2 实现案例](#2.2 实现案例)

3、优缺点分析

4、适用场景

5、实际应用


1、核心思想

目的:将指令信息封装成一个对象,并将此对象作为参数发送给接收方去执行,以使命令的请求方与执行方解耦

概念:命令是一个对象向另一个或多个对象发送的指令信息。命令的发送方负责下达指令,接收方则根据命令触发相应的行为。

举例

1> 遥控器对电视机发出的换台、调音量等指令

2> 将军针对士兵执行进攻、撤退或者先退再进的任务所下达的一系列命令

3> 餐厅中顾客为了让厨师按照自己的需求烹饪所需的菜品,需要与服务员确定的点菜单

4> 数据库的增、删、改、查:用户会向数据库发送SQL语句来执行相关操作,或提交回滚操作

2、实现方式

2.1 模式结构

五个核心角色:

  • Receiver(命令执行方):最终的命令执行方
  • Command(命令接口):定义命令执行的接口标准,可包括执行与反向执行操作。
  • ConcreteCommand(命令实现):命令接口的实现类,可以有任意多个,持有执行方对象的引用,其方法中调用命令执行方所对应的执行方法。
  • Invoker(命令请求方):命令的请求方或发送方,持有命令接口的引用,并控制命令的执行或反向执行操作。
  • Client(客户端):创建命令对象并关联接收者和调用者。

2.2 实现案例

遥控器控制家电:

java 复制代码
// 1、命令执行方
// 电灯
public class Light {
    public void on() {
        System.out.println("电灯已打开");
    }
    public void off() {
        System.out.println("电灯已关闭");
    }
}

// 风扇
public class Fan {
    public void on() {
        System.out.println("风扇已启动");
    }
    public void off() {
        System.out.println("风扇已停止");
    }
}


// 2、命令接口
public interface Command {
    void execute();   // 执行操作
    void undo();      // 撤销操作
}


// 3、命令实现
// 开灯命令
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 LightOffCommand implements Command {
    private Light light;

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

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

    @Override
    public void undo() {
        light.on();   // 撤销操作即开灯
    }
}

// 省略开风扇命令FanOnCommand、关风扇命令FanOffCommand


// 4、命令请求方:遥控器
public class RemoteControl {
    private Command command;
    private Stack<Command> history = new Stack<>();  // 记录操作历史

    public void setCommand(Command command) {
        this.command = command;
    }

    // 执行命令并记录历史
    public void pressButton() {
        command.execute();
        history.push(command);
    }

    // 撤销上一次操作
    public void pressUndo() {
        if (!history.isEmpty()) {
            Command lastCommand = history.pop();
            lastCommand.undo();
        }
    }
}

// 5、客户端
public class Client {
    public static void main(String[] args) {
        Light light = new Light();
        Fan fan = new Fan();

        // 创建命令对象
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);
        Command fanOn = new FanOnCommand(fan);
        Command fanOff = new FanOffCommand(fan);

        // 配置遥控器按钮
        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOn);
        remote.pressButton();  // 输出:电灯已打开
        remote.pressUndo();    // 输出:电灯已关闭(撤销)

        remote.setCommand(fanOn);
        remote.pressButton();  // 输出:风扇已启动
        remote.setCommand(fanOff);
        remote.pressButton();  // 输出:风扇已停止
        remote.pressUndo();    // 输出:风扇已启动(撤销)
    }
}

3、优缺点分析

优点:

  • 解耦请求发送者与接收者:调用者无需知道接收者的具体实现。

  • 支持撤销/重做:通过记录命令历史实现操作回退。

  • 灵活扩展命令:新增命令无需修改现有代码。

  • 支持宏命令:可组合多个命令为一个复合操作。

缺点:

  • 类数量增加:每个操作需一个具体命令类。

  • 复杂度提升:需要处理命令参数和状态管理。

4、适用场景

  • 需要撤销/重做功能

    • 如文本编辑器的撤销操作、事务回滚。
  • 异步任务队列

    • 将命令存入队列,延迟或按序执行。
  • GUI操作与业务逻辑解耦

    • 如按钮点击事件绑定不同命令。
  • 日志记录与恢复

    • 记录所有执行的命令,用于系统恢复。

5、实际应用

  • Java Swing的Action接口

    javax.swing.Action 是命令模式的典型实现,用于处理按钮、菜单项的操作。

  • 线程池任务队列

    RunnableCallable 对象作为命令提交到线程池执行。

  • 数据库事务

    每个SQL操作封装为命令对象,支持事务提交或回滚。

相关推荐
季鸢5 天前
Java设计模式之命令模式详解
java·设计模式·命令模式
小小数媒成员5 天前
命令模式,观察者模式,状态模式,享元模式
观察者模式·策略模式·命令模式
Echo``6 天前
8:OpenCV—仿射变换和坐标映射
开发语言·图像处理·人工智能·qt·opencv·计算机视觉·命令模式
暴躁哥7 天前
深入理解设计模式之命令模式
设计模式·命令模式
什么半岛铁盒12 天前
sockaddr结构体详解
编辑器·vim·命令模式
@Turbo@15 天前
【QT】一个界面中嵌入其它界面(三)
开发语言·qt·命令模式
干货日记15 天前
Qt与OpenGL绘制大全(加载obj模型文件、点、线、面、立方体、圆等)
开发语言·qt·命令模式
新手村领路人17 天前
qt5.14.2 opencv调用摄像头显示在label
qt·opencv·命令模式
xiaolin033317 天前
【设计模式】- 行为型模式1
设计模式·状态模式·责任链模式·策略模式·命令模式·模板方法模式·行为型模式