• 设计模式:命令模式


            命令模式(Command Pattern)是一种行为设计模式,它将请求封装成对象,以便参数化对象、延迟执行、记录请求日志、支持可撤销操作等。此模式基于“行动请求者”与“行动执行者”之间解耦的设计思想,使得请求的发送者和接收者之间没有直接的联系,通过命令对象作为中介,这样两者可以独立变化,提高系统的灵活性和可扩展性。

    主要参与者:

    1. Command(命令接口):定义所有命令的公共接口,声明执行操作的抽象方法 execute()。
    2. ConcreteCommand(具体命令类):实现 Command 接口,对接收到的请求进行封装处理,通常会持有 Receiver 的引用,并调用其方法来完成实际操作。
    3. Receiver(接收者):真正执行命令中操作的类,包含业务逻辑。它并不知道命令的存在,只是单纯地执行操作。
    4. Invoker(调用者/请求者):负责调用命令对象的 execute() 方法,发出请求。它并不直接调用接收者的操作方法,而是通过命令对象间接调用。

    优点:

    • 低耦合:命令模式将调用操作的对象与知道如何实现该操作的对象分离开来,降低了系统的耦合度。
    • 扩展性:添加新的命令非常容易,只需要添加新的 ConcreteCommand 类即可,符合“开闭原则”。
    • 灵活性:命令可以存储、队列化、记录日志、支持撤销/重做等功能,丰富了系统的可操控性。
    • 支持宏命令:可以将多个命令组合成一个复合命令,即一个命令执行多个操作。

    应用场景:

    • 用户界面(UI)设计,如按钮点击事件的处理。
    • 日志记录、事务管理等需要支持回滚操作的场景。
    • 支持批处理作业的系统,如定时任务调度。
    • 需要提供可撤销/重做功能的软件,如文本编辑器。

    示例代码(Java):

            下面是一个使用Java实现命令模式的完整示例。在这个例子中,我们将模拟一个智能家居场景,其中包括一个智能灯泡和一个遥控器。遥控器可以用来开关灯泡,而开关操作将通过命令模式来实现。

    1. 定义命令接口

       首先,定义一个命令接口 Command,声明执行操作的方法 execute()

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

    2. 实现具体命令

        接着,创建两个具体命令类 LightOnCommandLightOffCommand,它们实现了 Command 接口,并且分别对应着打开和关闭灯的操作。每个命令类都会持有一个 Light 对象的引用,以便操作灯。

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

    3. 定义接收者

      Light 类作为接收者,它包含实际执行动作的方法 turnOn()turnOff()

    1. 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. }

    4. 创建调用者/请求者

      RemoteControl 类作为调用者,它持有一个 Command 类型的成员变量,并提供方法 setCommand() 来设置命令,以及 buttonPressed() 来执行当前设置的命令。

    1. class RemoteControl {
    2. private Command command;
    3. public void setCommand(Command command) {
    4. this.command = command;
    5. }
    6. public void buttonPressed() {
    7. command.execute();
    8. }
    9. }

    5. 客户端代码

            最后,客户端代码创建 Light 对象、LightOnCommandLightOffCommand 对象,以及 RemoteControl 对象,并通过遥控器控制灯的开关。

    1. public class CommandPatternDemo {
    2. public static void main(String[] args) {
    3. // 创建接收者对象
    4. Light light = new Light();
    5. // 创建命令对象
    6. Command lightOnCommand = new LightOnCommand(light);
    7. Command lightOffCommand = new LightOffCommand(light);
    8. // 创建调用者对象
    9. RemoteControl remoteControl = new RemoteControl();
    10. // 设置命令
    11. remoteControl.setCommand(lightOnCommand);
    12. System.out.println("Pressing ON button...");
    13. remoteControl.buttonPressed(); // 输出 "Light is on"
    14. remoteControl.setCommand(lightOffCommand);
    15. System.out.println("Pressing OFF button...");
    16. remoteControl.buttonPressed(); // 输出 "Light is off"
    17. }
    18. }

         这个例子展示了如何使用命令模式来解耦请求的发起者(遥控器)和请求的处理者(灯),使得添加新的命令或者更改现有命令的执行逻辑变得简单且灵活。

  • 相关阅读:
    【微服务保护】初识 Sentinel —— 探索微服务雪崩问题的解决方案,Sentinel 的安装部署以及将 Sentinel 集成到微服务项目
    (三)Apache log4net™ 手册 -演示
    Spring Cloud Alibaba Sentinel 简单使用
    [JavaScript][AJAX] axios框架 ,页面跳转传参,DOM驱动,数据驱动渲染页面,tab切换,网络请求loading动画
    Mac使用hsdis查看java字节码的汇编命令
    【灾备】灾难恢复
    【Promise】黑马vue视频笔记(十一)
    Sharding sphere分库分表
    Caffeine本地缓存学习
    前端例程20220728:按钮点击涟漪效果
  • 原文地址:https://blog.csdn.net/K___End/article/details/138565933