设计模式:命令模式(Command Pattern)及实例
好家伙,
0.什么是命令模式
在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。
但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。
在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)。

0.1.角色解释
Command(定义接口): 定义命令的接口,声明执行的方法。
ConcreteCommand(实现接口):命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
Receiver(接收者):接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
Invoker(调用者):要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。
这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
Client(具体命令):创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,
把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行
0.2.模式分析
0.3.模式优点
0.4.缺点
1.实例
想象一个实例
餐厅点餐案例
现在我走进一家餐厅,向一名服务员点餐,点了一份牛肉汉堡,
服务员将这份”牛肉汉堡"订单交给厨师,厨师制作这份牛肉牛肉汉堡
来个代码实现
// 厨师类
class Chef {
makeBurger() {
console.log("This is your burger.");
}
} // 服务员类
class Waitress {
constructor(chef) {
this.chef = chef;
} takeOrder(order) {
// 服务员接收订单并处理
console.log("Waitress is taking the order for a " + order);
this.chef.makeBurger(); // 直接通知厨师制作汉堡
}
} // 客户端代码
(() => {
const chef = new Chef();
const waitress = new Waitress(chef); // 客户点餐 服务员通知
waitress.takeOrder("burger");
})();
那么如果我使用命令模式去实现呢?
// 命令接口(抽象概念,使用ES6的类来表示)
class Command {
execute() {
// 抽象方法execute,将在具体命令中实现
throw new Error('You should implement the execute method');
}
} // 具体命令类
class OrderBurgerCommand extends Command {
constructor(receiver) {
super();
this.receiver = receiver;
} execute() {
this.receiver.makeBurger();
}
} // 接收者类
class Chef {
makeBurger() {
console.log("Chef is making a burger.");
}
} // 请求者类
class Waitress {
constructor() {
this.commands = [];
} takeOrder(command) {
if (!(command instanceof Command)) {
throw new Error('You can only take order of Command instances');
}
this.commands.push(command);
} notify() {
this.commands.forEach(command => command.execute());
}
} // 客户类
class Customer {
constructor() {
this.waitress = new Waitress();
this.chef = new Chef();
this.burgerCommand = new OrderBurgerCommand(this.chef);
} orderBurger() {
this.waitress.takeOrder(this.burgerCommand);
} serveOrder() {
this.waitress.notify();
}
} // 客户端代码
(() => {
const customer = new Customer();
customer.orderBurger(); // 客户点餐
customer.serveOrder(); // 服务员通知厨师制作汉堡
})();
2.增加需求
同样的,如果我们新下单一条“薯条”
使用命令模式
// 命令模式实现 // 命令接口
class Command {
execute() {
// 抽象方法,需要在子类中实现
}
} // 汉堡命令
class BurgerCommand extends Command {
constructor(chef) {
super();
this.chef = chef;
} execute() {
this.chef.makeBurger();
}
} // 薯条命令
class FrenchFriesCommand extends Command {
constructor(chef) {
super();
this.chef = chef;
} execute() {
this.chef.makeFrenchFries();
}
} // 厨师类
class Chef {
makeBurger() {
console.log('制作汉堡');
} makeFrenchFries() {
console.log('制作薯条');
}
} // 服务员类
class Waiter {
constructor() {
this.commands = [];
} order(command) {
this.commands.push(command);
console.log('订单已接收');
} serve() {
this.commands.forEach(command => command.execute());
}
} // 客户类
class Customer {
constructor(waiter) {
this.waiter = waiter;
} orderBurger() {
const chef = new Chef();
const burgerCommand = new BurgerCommand(chef);
this.waiter.order(burgerCommand);
} orderFrenchFries() {
const chef = new Chef();
const friesCommand = new FrenchFriesCommand(chef);
this.waiter.order(friesCommand);
}
} // 客户端代码
(() => {
const waiter = new Waiter();
const customer = new Customer(waiter); // 客户点一份汉堡
customer.orderBurger(); // 客户再点一份薯条
customer.orderFrenchFries(); // 服务员开始服务
waiter.serve();
})();
再结合以上代码来看,命令模式的优势有
1.真正实现了解耦:客户不需要知道汉堡制作的细节,服务员也不需要知道汉堡制作的细节,客户仅仅是下单,服务员仅仅是通知
2.易于扩展:如果需要添加新的操作(如包装、加热),可以创建新的命令类,而无需修改现有的类结构。
通过汉堡和薯条的例子,我们可以看到命令模式如何使得代码更加灵活、可维护,并且更容易进行扩展。
设计模式:命令模式(Command Pattern)及实例的更多相关文章
- 设计模式 - 命令模式(command pattern) 多命令 具体解释
命令模式(command pattern) 多命令 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.csdn.ne ...
- 设计模式 - 命令模式(command pattern) 具体解释
命令模式(command pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 命令模式(command pattern) : 将请求封装成对 ...
- 设计模式 - 命令模式(command pattern) 宏命令(macro command) 具体解释
命令模式(command pattern) 宏命令(macro command) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考: 命名模式(撤销) ...
- 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释
命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...
- 大话设计模式--命令模式 Command -- C++实现实例
1. 命令模式: 将请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作. 命令模式有点: a. 较容易的设计一个命令队列 b. 在需要的的情况 ...
- C#设计模式——命令模式(Command Pattern)
一.概述通常来说,“行为请求者”与“行为实现者”是紧耦合的.但在某些场合,比如要对行为进行“记录.撤销/重做.事务”等处理,这种无法抵御变化的紧耦合是不合适的.在这些情况下,将“行为请求者”与“行为实 ...
- 乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...
- 二十四种设计模式:命令模式(Command Pattern)
命令模式(Command Pattern) 介绍将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例有一个Message实体类,某个 ...
- 设计模式-15命令模式(Command Pattern)
1.模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使 ...
- 设计模式(六):控制台中的“命令模式”(Command Pattern)
今天的博客中就来系统的整理一下“命令模式”.说到命令模式,我就想起了控制台(Console)中的命令.无论是Windows操作系统(cmd.exe)还是Linux操作系统(命令行式shell(Comm ...
随机推荐
- 配置服务器SSH PAM防止暴力破解
正常机器如果开启ssh可能会被暴力破解用户密码,可以配置ssh的pam限制登录失败时可以锁定用户一段时间,就算密码输入正确也无法登录,等恢复之后才可以再次进入,对于不同的发行版配置可能略有不同,对于r ...
- 力扣609(java&python)-在系统中查找重复文件(中等)
给你一个目录信息列表 paths ,包括目录路径,以及该目录中的所有文件及其内容,请你按路径返回文件系统中的所有重复文件.答案可按 任意顺序 返回. 一组重复的文件至少包括 两个 具有完全相同内容的文 ...
- HarmonyOS NEXT应用开发之使用AKI轻松实现跨语言调用
介绍 针对JS与C/C++跨语言访问场景,NAPI使用比较繁琐.而AKI提供了极简语法糖使用方式,一行代码完成JS与C/C++的无障碍跨语言互调,使用方便.本示例将介绍使用AKI编写C++跨线程调用J ...
- 【开发者成长】喧哗的背后:Serverless 的挑战
作者 | 许晓斌 阿里云高级技术专家,目前负责阿里集团 Serverless 研发运维平台建设,<Maven 实战>作者,曾经是 Maven 中央仓库的维护者. 导读:本文作者作为阿里集 ...
- Dubbo-go 优雅上下线设计与实践
简介:在分布式场景下,微服务进程都是以容器的形式存在,在容器调度系统例如 k8s 的支持下运行,容器组 Pod 是 K8S 的最小资源单位.随着服务的迭代和更新,当新版本上线后,需要针对线上正在运行 ...
- HBase读链路分析
简介:HBase的存储引擎是基于LSM-Like树实现的,更新操作不会直接去更新数据,而是使用各种type字段(put,delete)来标记一个新的多版本数据,采用定期compaction的形式来归 ...
- 如何通过Graph+AI的方法打造高精度风控模型
简介: 阿里云图智能平台在金融行业已经帮助银行.保险等领域客户构建了金融风控.商品推荐.循环担保检测.异常指标监控.违规团伙挖掘等场景,通过穿透行业应用场景,帮助客户基于多维数据做出精准决策. > ...
- 打通JAVA与内核系列之一ReentrantLock锁的实现原理
简介:写JAVA代码的同学都知道,JAVA里的锁有两大类,一类是synchronized锁,一类是concurrent包里的锁(JUC锁).其中synchronized锁是JAVA语言层面提供的能力 ...
- 阿里巴巴 DevOps 工具体系
简介: 随着阿里巴巴多元化业务 20 多年的高速发展,技术体系经历了 web 时代.移动化时代.数据智能时代.云计算时代等多个重大变革.在这些变革中,开发者面对的技术体系.工具体系.知识体系也在不断 ...
- k3s安装---适配边缘计算场景的轻量级的k8s(二)
三.安装k8s k3s官网:https://k3s.io 文档: github:https://github.com/k3s-io/k3s 3.1 安装基础环境 # 安装基础环境 1.安装yum源 c ...