【设计模式】【行为型模式(Behavioral Patterns)】之命令模式(Command Pattern)

embedded/2024/11/28 20:46:38/

1. 设计模式原理说明

命令模式(Command Pattern) 是一种行为设计模式,它将请求封装成对象,从而使你可以用不同的请求对客户进行参数化、队列请求或将请求日志化,同时支持可撤销的操作。通过这种方式,可以将请求发送者与接收者解耦,使得两者之间不再直接联系,而是通过命令对象进行交互。

主要角色
  1. Command(命令接口):声明执行操作的接口。
  2. ConcreteCommand(具体命令):将接收者对象与动作绑定,调用接收者相应的操作,实现Command接口。
  3. Receiver(接收者):知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
  4. Invoker(调用者):要求该命令执行这个请求,它依赖于Command。
  5. Client(客户端):创建具体的命令对象,并设置其接收者。

2. UML 类图及解释

UML 类图
+-----------------+                +-----------------+
|   Command       |                |    Receiver     |
|-----------------|                |-----------------|
| - execute()     |                | - action()      |
+-----------------+                +-----------------+^                               ^|                               ||                               |v                               v
+-----------------+                +-----------------+
| ConcreteCommand |                |   ConcreteReceiver|
|-----------------|                |-----------------|
| - receiver: Receiver |            | - action()      |
| - execute()      |                +-----------------+
+-----------------+                    ^||v
+-----------------+
|     Invoker     |
|-----------------|
| - command: Command |
| - setCommand(command: Command) |
| - executeCommand() |
+-----------------+
类图解释
  • Command:定义了执行操作的接口。
  • ConcreteCommand:实现了Command接口,将接收者对象与动作绑定。
  • Receiver:执行具体的操作,可以是任何类。
  • Invoker:负责调用命令对象的execute方法,但不关心具体执行什么操作。
  • Client:创建命令对象并设置接收者,然后将命令对象传递给调用者。

3. 代码案例及逻辑详解

Java 代码案例
// 命令接口
interface Command {void execute();
}// 接收者
class Receiver {public void action() {System.out.println("Executing action");}
}// 具体命令
class ConcreteCommand implements Command {private Receiver receiver;public ConcreteCommand(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.action();}
}// 调用者
class Invoker {private Command command;public void setCommand(Command command) {this.command = command;}public void executeCommand() {if (command != null) {command.execute();}}
}// 客户端
public class Client {public static void main(String[] args) {Receiver receiver = new Receiver();Command command = new ConcreteCommand(receiver);Invoker invoker = new Invoker();invoker.setCommand(command);invoker.executeCommand();}
}
C++ 代码案例
#include <iostream>// 命令接口
class Command {
public:virtual ~Command() {}virtual void execute() = 0;
};// 接收者
class Receiver {
public:void action() {std::cout << "Executing action" << std::endl;}
};// 具体命令
class ConcreteCommand : public Command {
private:Receiver* receiver;
public:ConcreteCommand(Receiver* receiver) : receiver(receiver) {}void execute() override {receiver->action();}
};// 调用者
class Invoker {
private:Command* command;
public:void setCommand(Command* command) {this->command = command;}void executeCommand() {if (command != nullptr) {command->execute();}}
};// 客户端
int main() {Receiver receiver;Command* command = new ConcreteCommand(&receiver);Invoker invoker;invoker.setCommand(command);invoker.executeCommand();delete command;return 0;
}
Python 代码案例
# 命令接口
class Command:def execute(self):raise NotImplementedError# 接收者
class Receiver:def action(self):print("Executing action")# 具体命令
class ConcreteCommand(Command):def __init__(self, receiver):self.receiver = receiverdef execute(self):self.receiver.action()# 调用者
class Invoker:def __init__(self):self.command = Nonedef set_command(self, command):self.command = commanddef execute_command(self):if self.command:self.command.execute()# 客户端
if __name__ == "__main__":receiver = Receiver()command = ConcreteCommand(receiver)invoker = Invoker()invoker.set_command(command)invoker.execute_command()
Go 代码案例
package mainimport ("fmt"
)// 命令接口
type Command interface {execute()
}// 接收者
type Receiver struct{}func (r *Receiver) action() {fmt.Println("Executing action")
}// 具体命令
type ConcreteCommand struct {receiver *Receiver
}func (c *ConcreteCommand) execute() {c.receiver.action()
}// 调用者
type Invoker struct {command Command
}func (i *Invoker) setCommand(command Command) {i.command = command
}func (i *Invoker) executeCommand() {if i.command != nil {i.command.execute()}
}// 客户端
func main() {receiver := &Receiver{}command := &ConcreteCommand{receiver: receiver}invoker := &Invoker{}invoker.setCommand(command)invoker.executeCommand()
}

4. 总结

命令模式 是一种行为设计模式,它将请求封装成对象,从而使你可以用不同的请求对客户进行参数化、队列请求或将请求日志化,同时支持可撤销的操作。通过这种方式,可以将请求发送者与接收者解耦,使得两者之间不再直接联系,而是通过命令对象进行交互。

主要优点
  1. 解耦命令模式将请求的发送者和接收者解耦,使得两者之间不再直接联系。
  2. 扩展性:新增命令时,只需添加新的具体命令类,无需修改现有代码,符合开闭原则。
  3. 支持撤销操作:命令对象可以保存状态,从而支持撤销和重做操作。
  4. 支持队列请求:可以将命令对象放入队列中,实现异步处理。
主要缺点
  1. 增加系统复杂度:引入命令模式会增加系统的复杂度,因为需要额外的命令类和调用者类。
  2. 性能开销命令模式可能会带来一些性能开销,特别是在命令对象较多时。
适用场景
  • 当需要将请求排队或记录请求日志,或者支持可撤销操作时。
  • 当需要参数化对象来指定要执行的操作时。
  • 当需要在不同的时刻指定、排列和执行请求时。
  • 当需要将请求发送者与接收者解耦时。

http://www.ppmy.cn/embedded/141258.html

相关文章

【R库包安装】R库包安装总结:conda、CRAN等

【R库包安装】R studio 安装rgdal库/BPST库 R studio 安装rgdal库解决方法 R studio 安装BPST库&#xff08;github&#xff09;解决方法方法1&#xff1a;使用devtools安装方法2&#xff1a;下载安装包直接在Rstudio中安装 参考 基础 R 库包的安装可参见另一博客-【R库包安装】…

iOS 17.4 Not Installed

0x00 系统警告 没有安装 17.4 的模拟器&#xff0c;任何操作都无法进行&#xff01; 点击 OK 去下载&#xff0c;完成之后&#xff0c;依旧是原样&#xff01; 0x01 解决办法 1、先去官网下载对应的模拟器&#xff1a; https://developer.apple.com/download/all/?q17.4 …

JavaWeb开发深度解析:构建高效、可扩展的Web应用

JavaWeb开发深度解析&#xff1a;构建高效、可扩展的Web应用 在当今数字化时代&#xff0c;Web应用已成为企业连接用户、提供服务的关键渠道。JavaWeb&#xff0c;凭借其强大的跨平台能力、丰富的框架支持和成熟的社区资源&#xff0c;成为了构建企业级Web应用的首选技术栈之一…

【HarmonyOS】@Observed和@ObjectLink嵌套对象属性更改UI不刷新问题

【HarmonyOS】Observed和ObjectLink嵌套对象属性更改UI不刷新问题 一、问题背景 使用了Observed和ObjectLink&#xff0c;修改嵌套对象的属性&#xff0c;UI还是不刷新&#xff0c;常见的问题有以下三种形式&#xff1a; 1.多级嵌套&#xff0c;嵌套对象的类并没有添加Observ…

Linux系统Docker部署开源在线协作笔记Trilium Notes与远程访问详细教程

目录 ⛳️推荐 前言 1. 安装docker与docker-compose 2. 启动容器运行镜像 3. 本地访问测试 4.安装内网穿透 5. 创建公网地址 6. 创建固定公网地址 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下…

小程序-基于java+SpringBoot+Vue的网上花店微信小程序设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

Vue2中 vuex 的使用

1.安装 vuex 安装vuex与vue-router类似&#xff0c;vuex是一个独立存在的插件&#xff0c;如果脚手架初始化没有选 vuex&#xff0c;就需要额外安装。 yarn add vuex3 或者 npm i vuex3 233 Vue2 Vue-Router3 Vuex3 344 Vue3 Vue-Router4 Vuex4 2. 新建 store/index.j…

git源码安装

源码安装。执行以下步骤&#xff1a; 使用"wget"命令下载Git源码包&#xff0c;例如&#xff1a;"wget https://www.kernel.org/pub/software/scm/git/git-2.0.5.tar.gz"。 使用"tar"命令解压缩下载的源码包&#xff0c;例如&#xff1a;"…