• 23种设计模式之:命令模式


    命令模式是一种行为设计模式,它将一个请求封装成一个对象,从而让你使用不同的请求、队列或者请求的日志来参数化其他对象。它也支持可撤销的操作。命令模式的关键是引入了抽象层——命令接口,具体命令实现该接口,执行操作的对象从执行具体操作的职责中解耦出来。

    使用场景

    • 当你需要参数化对象根据请求来执行操作时,可以使用命令模式,因为它可以指定和执行请求。
    • 当你需要在不同的时间指定、排队和执行请求时。命令对象可以在一个队列中排队,并在稍后执行。
    • 当需要支持撤销操作时。命令模式可以将状态回滚到某个命令被执行之前的状态。
    • 当你需要将操作组装成复杂操作时,可以使用命令模式,它支持组合命令。

    好处

    • 降低耦合度:命令模式通过引入命令接口,使得请求的发送者和接收者解耦,增加新的命令很方便,不需要改动旧的代码。
    • 增强可扩展性:可以很容易地添加新命令,只需实现接口即可。
    • 支持撤销操作:可以通过实现撤销方法来轻松支持撤销。
    • 可以组合命令:可以将多个命令组装成宏命令,一次性执行多个操作。

    Java代码演示

    接收者(Receiver)

    接收者类Light实际执行与请求相关的操作:

    1. public class Light {
    2. public void turnOn() {
    3. System.out.println("Light is on");
    4. }
    5. public void turnOff() {
    6. System.out.println("Light is off");
    7. }
    8. }

    命令接口(Command)

    命令接口定义了执行操作的方法:

    1. public interface Command {
    2. void execute();
    3. }

    具体命令(Concrete Commands)

    具体命令实现命令接口,并定义接收者和操作之间的绑定关系:

    1. public class LightOnCommand implements Command {
    2. private Light light;
    3. public LightOnCommand(Light light) {
    4. this.light = light;
    5. }
    6. @Override
    7. public void execute() {
    8. light.turnOn();
    9. }
    10. }
    11. public class LightOffCommand implements Command {
    12. private Light light;
    13. public LightOffCommand(Light light) {
    14. this.light = light;
    15. }
    16. @Override
    17. public void execute() {
    18. light.turnOff();
    19. }
    20. }

    调用者(Invoker)

    调用者持有命令对象,并在某个时间点调用命令对象的execute()方法:

    1. public class RemoteControl {
    2. private Command command;
    3. public void setCommand(Command command) {
    4. this.command = command;
    5. }
    6. public void pressButton() {
    7. if (command != null) {
    8. command.execute();
    9. }
    10. }
    11. }

    客户端(Client)

    客户端决定哪个命令执行,以及它的接收者是谁:

    1. public class Client {
    2. public static void main(String[] args) {
    3. // 创建接收者
    4. Light light = new Light();
    5. // 创建命令,并设置其接收者
    6. Command lightsOn = new LightOnCommand(light);
    7. Command lightsOff = new LightOffCommand(light);
    8. // 创建调用者,并关联命令
    9. RemoteControl control = new RemoteControl();
    10. control.setCommand(lightsOn); // 设置开灯命令
    11. control.pressButton(); // 执行开灯命令
    12. control.setCommand(lightsOff); // 设置关灯命令
    13. control.pressButton(); // 执行关灯命令
    14. }
    15. }

    命令模式的好处

    通过这个更完整的示例,我们可以看到命令模式的几个关键好处:

    • 解耦调用操作和接收者RemoteControl(调用者)不直接操作Light(接收者),而是通过命令对象进行间接操作。这意味着Light类的任何变化都不会直接影响到RemoteControl类,反之亦然。
    • 易于扩展:要增加新的命令操作,只需添加一个新的Command实现即可,无需修改现有的InvokerReceiver类。
    • 组合命令:可以很容易地实现宏命令,即一个命令触发多个操作。

    这样,使用命令模式提供了代码的灵活性和扩展性,同时也使得操作的撤销和重做成为可能。

  • 相关阅读:
    【JavaEE】MyBatis
    Compose原理-视图和数据双向绑定的原理
    Abnova丨 CD81单克隆抗体相关参数和应用
    奇异矩阵、非奇异矩阵
    Springboot 开发env
    这个技术值得拥有 - 录制细胞生物反应的实时小电影
    conda环境安装opencv带cuda版本
    [附源码]计算机毕业设计基于springboot学习互助辅助系统
    SpringSecurity-基于Web的认证与权限访问
    (十)C++中的左值lvalue&右值rvaue
  • 原文地址:https://blog.csdn.net/www_tlj/article/details/136134221