当前位置: 首页 > news >正文

命令模式(请求与具体实现解耦)

目录

前言

UML

plantuml

类图

实战代码

模板

Command

Invoker

Receiver

Client


前言

命令模式解耦了命令请求者(Invoker)和命令执行者(receiver),使得 Invoker 不再直接引用 receiver,而是依赖于抽象的命令接口。具体的命令类则直接引用 receiver,通过调用 receiver 的方法来执行命令。

解耦之后,具体命令的增删改不再影响 Invoker,同时,抽象出来的命令请求还能队列化,从而实现撤销和重试功能,或做排列组合合成复杂的命令。

在 Invoker 中,也体现了桥接模式的思想,将命令的抽象和具体的实现分离,使 Invoker 中命令的添加和扩展更加简单。不过具体的命令类并不直接实现处理逻辑,而是交给了 receiver 来实现,这也是命令模式和桥接模式最主要的区别。

UML

plantuml

@startuml
'https://plantuml.com/class-diagram

interface Command {
    + execute() : void
}

class CommandA {
    - receiver : Receiver
    + CommandA(Receiver)
    + execute() : void
}

class CommandB {
    - receiver : Receiver
    + CommandB(Receiver)
    + execute() : void
}

class Receiver {
    + executeA() : void
    + executeB() : void
}

class Invoker {
    - commands : List<Command>
    + addCommand(Command) : void
    + execute(Command) : void
    + executes() : void
}

class Client {}

Command <|.. CommandA
Command <|.. CommandB

CommandA "1" --> "1" Receiver
CommandB "1" --> "1" Receiver

Invoker "1" --> "n" Command

Client ..> Invoker
Client ..> Command

@enduml

类图

实战代码

模板

Command

public interface Command {
    void execute();
}

public class ConcreteCommand1 implements Command {
    private Receiver receiver;

    public ConcreteCommand1(Receiver receiver) {
        this.receiver = receiver;
    }

    public void execute() {
        receiver.execute1();
    }
}


public class ConcreteCommand2 implements Command {
    private Receiver receiver;

    public ConcreteCommand2(Receiver receiver) {
        this.receiver = receiver;
    }

    public void execute() {
        receiver.execute2();
    }
}

Invoker

public class Invoker {
    private List<Command> commands = new ArrayList<Command>();
    public void addCommand(Command command){
        commands.add(command);
    }

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

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

Receiver

public class Receiver {
    public void execute1() {
        System.out.println("execute1.");
    }

    public void execute2() {
        System.out.println("execute2.");
    }
}

Client

public class Test {
    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        
        Invoker invoker = new Invoker();

        invoker.execute(new Command1(receiver));

        invoker.addAction(new Command1(receiver));
        invoker.addAction(new Command2(receiver));
        invoker.executes();
    }
}

相关文章:

  • Photoshop 工具使用详解(全集 · 2024版)
  • hdlbits系列verilog解答(Adder3)-67
  • 2024-03-26 Android8.1 px30 WI-FI 模块rtl8821cu调试记录
  • 数学分析复习:实数项级数的收敛
  • python --dejavu音频指纹识别
  • 【面试经典150 | 动态规划】零钱兑换
  • MySQL 8.0 支持对单个数据库设置只读!
  • Oracle:ORA-01830错误-更改数据库时间格式
  • Eureka和Nacos的关系
  • C++之std::mem_fn使用和实现原理(全)
  • OpenAI跨界好莱坞:Sora电影制作工具即将登场,首曝剧情片细节及试用者评价
  • 【Linux】详细分析/dev/loop的基本知识 | 空间满了的解决方法
  • 【前端面试3+1】02插槽、箭头函数与普通函数、重绘重排、【回文数】
  • 计算机网络——数据链路层(差错控制)
  • 微软Microsoft Surface Go 2
  • 将word转为PDF的几种简单方式
  • Day48:WEB攻防-PHP应用文件上传中间件CVE解析第三方编辑器已知CMS漏洞
  • CMake学习笔记(一)一个最简单的CMakeLists嵌套示例
  • 使用Urllib库创建第一个爬虫程序
  • 创新研报 | 2024+人工智能安全报告
  • https://app.hackthebox.com/machines/Inject
  • Spring —— Spring简单的读取和存储对象 Ⅱ
  • 渗透测试之冰蝎实战
  • Mybatis、TKMybatis对比
  • Microsoft Office 2019(2022年10月批量许可版)图文教程
  • 《谷粒商城基础篇》分布式基础环境搭建
  • 哈希表题目:砖墙
  • Vue 3.0 选项 生命周期钩子
  • 【车载嵌入式开发】AutoSar架构入门介绍篇
  • 【计算机视觉 | 目标检测】DETR风格的目标检测框架解读