java设计模式:04-02-命令模式

命令模式 (Command Pattern)

命令模式是一种行为设计模式,它将请求封装成对象,从而使您可以用不同的请求、队列或日志来参数化其他对象。命令模式也支持可撤销的操作。

应用场景
  1. 事务处理系统:需要对一系列操作进行封装,并提供回滚功能。
  2. GUI开发:例如按钮点击的处理逻辑,可以使用命令模式将操作和按钮的点击事件解耦。
  3. 宏命令:组合多个操作命令,形成一个复合命令。
  4. 日志记录:在系统崩溃后,通过日志重现命令执行的过程。

实现方式

1. 基本命令模式

思想:将请求封装成独立的命令对象,使得命令的调用者与执行者解耦。

实现方式

java 复制代码
// 命令接口
interface Command {
    void execute();
}

// 具体命令
class LightOnCommand implements Command {
    private Light light;

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

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

// 接收者
class Light {
    public void on() {
        System.out.println("The light is on");
    }

    public void off() {
        System.out.println("The light is off");
    }
}

// 调用者
class RemoteControl {
    private Command command;

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

    public void pressButton() {
        command.execute();
    }
}

// 客户端代码
public class CommandPatternDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);

        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOn);
        remote.pressButton();
    }
}

优点

  • 解耦请求的发送者和接收者:使得发送者不需要知道接收者的具体实现。
  • 扩展性强:可以方便地新增命令。
  • 支持撤销操作:可以通过存储历史命令来支持撤销和重做操作。

缺点

  • 类的数量增加:每一个具体命令都需要一个对应的类。
2. 带撤销功能的命令模式

思想:在基本命令模式的基础上,增加对撤销操作的支持。

实现方式

java 复制代码
// 命令接口
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 Light {
    public void on() {
        System.out.println("The light is on");
    }

    public void off() {
        System.out.println("The light is off");
    }
}

// 调用者
class RemoteControl {
    private Command command;

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

    public void pressButton() {
        command.execute();
    }

    public void pressUndo() {
        command.undo();
    }
}

// 客户端代码
public class CommandPatternDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOn);
        remote.pressButton();
        remote.pressUndo();

        remote.setCommand(lightOff);
        remote.pressButton();
        remote.pressUndo();
    }
}

优点

  • 支持撤销和重做操作:可以通过存储命令的历史记录来支持撤销和重做。
  • 解耦请求的发送者和接收者:发送者不需要知道接收者的具体实现。

缺点

  • 类的数量增加:每一个具体命令都需要一个对应的类。
  • 维护命令历史:需要额外的代码来维护命令历史。
3. 宏命令模式

思想:将多个命令组合成一个复合命令,使得一组命令可以一次执行。

实现方式

java 复制代码
// 命令接口
interface Command {
    void execute();
}

// 具体命令
class LightOnCommand implements Command {
    private Light light;

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

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

// 具体命令
class LightOffCommand implements Command {
    private Light light;

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

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

// 宏命令
class MacroCommand implements Command {
    private List<Command> commands;

    public MacroCommand() {
        commands = new ArrayList<>();
    }

    public void addCommand(Command command) {
        commands.add(command);
    }

    public void execute() {
        for (Command command : commands) {
            command.execute();
        }
    }
}

// 接收者
class Light {
    public void on() {
        System.out.println("The light is on");
    }

    public void off() {
        System.out.println("The light is off");
    }
}

// 客户端代码
public class MacroCommandPatternDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        MacroCommand macro = new MacroCommand();
        macro.addCommand(lightOn);
        macro.addCommand(lightOff);

        macro.execute();
    }
}

优点

  • 组合命令:可以将多个命令组合成一个复合命令,简化客户端代码。
  • 增强灵活性:可以动态添加或删除命令。

缺点

  • 类的数量增加:每一个具体命令都需要一个对应的类。
  • 命令依赖:命令之间可能存在依赖关系,需小心处理。

总结

命令模式 优点 缺点
基本命令模式 解耦请求的发送者和接收者,扩展性强 类的数量增加
带撤销功能的命令模式 支持撤销和重做操作,解耦请求的发送者和接收者 类的数量增加,维护命令历史
宏命令模式 组合命令,增强灵活性 类的数量增加,命令依赖

选择哪种实现方式应根据具体的需求和系统的复杂度来决定。基本命令模式适用于一般的请求封装场景,带撤销功能的命令模式适用于需要撤销和重做操作的场景,宏命令模式适用于需要组合多个操作的场景。通过合理的设计,可以充分利用命令模式的优势,解耦请求的发送者和接收者,提高系统的灵活性和可扩展性。

相关推荐
mghio6 小时前
Dubbo 中的集群容错
java·微服务·dubbo
千千寰宇8 小时前
[设计模式/Java/多线程] 设计模式之单例模式【9】
设计模式·操作系统-进程/线程/并发
咖啡教室11 小时前
java日常开发笔记和开发问题记录
java
咖啡教室11 小时前
java练习项目记录笔记
java
鱼樱前端12 小时前
maven的基础安装和使用--mac/window版本
java·后端
RainbowSea13 小时前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq
RainbowSea13 小时前
5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
java·消息队列·rabbitmq
李少兄14 小时前
Unirest:优雅的Java HTTP客户端库
java·开发语言·http
此木|西贝14 小时前
【设计模式】原型模式
java·设计模式·原型模式