初识设计模式——命令模式(Command Pattern)
命令模式(Command Pattern)是一种行为设计模式,它把请求封装成一个对象,从而允许你用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式的构成
- 命令(Command):定义了执行操作的接口,通常包含一个执行方法execute()。
- 具体命令(Concrete Command):实现了命令接口,负责调用接收者的相应操作。
- 接收者(Receiver):知道如何执行与请求相关的操作,是实际执行命令的对象。
- 调用者(Invoker):负责调用命令对象执行请求,不关心命令的具体实现。
- 客户端(Client):创建具体命令对象,并设置其接收者,然后将命令对象传递给调用者。

案例
场景
在一个 Web 应用中,我们可能需要处理用户的不同操作,例如用户点击按钮时执行不同的业务逻辑。这里以用户点击 “保存” 和 “删除” 按钮为例,使用命令模式来实现。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| <?php
class ArticleService { public function save() { echo "文章已保存\n"; }
public function delete() { echo "文章已删除\n"; } }
interface Command { public function execute(); }
class SaveArticleCommand implements Command { private $articleService;
public function __construct(ArticleService $articleService) { $this->articleService = $articleService; }
public function execute() { $this->articleService->save(); } }
class DeleteArticleCommand implements Command { private $articleService;
public function __construct(ArticleService $articleService) { $this->articleService = $articleService; }
public function execute() { $this->articleService->delete(); } }
class ButtonInvoker { private $command;
public function setCommand(Command $command) { $this->command = $command; }
public function click() { $this->command->execute(); } }
$articleService = new ArticleService(); $saveCommand = new SaveArticleCommand($articleService); $deleteCommand = new DeleteArticleCommand($articleService);
$button = new ButtonInvoker();
$button->setCommand($saveCommand); $button->click();
$button->setCommand($deleteCommand); $button->click();
|
UML类图

命令模式的适用场景
- 需要对请求进行记录、排队、撤销、重做等操作:例如,在文本编辑器中,撤销和重做功能可以通过命令模式来实现。
- 需要将请求的发送者和接收者解耦:当发送者和接收者之间的关系复杂,或者发送者不关心接收者的具体实现时,可以使用命令模式。
- 需要在不同的时间指定、排列和执行请求:例如,在任务调度系统中,可以使用命令模式来管理和执行任务。
命令模式的优缺点
优点
- 解耦:将请求的发送者和接收者解耦,提高了系统的可扩展性和可维护性。
- 可扩展性:可以很容易地添加新的命令类,而不需要修改现有的代码。
- 支持撤销和重做:可以方便地实现命令的撤销和重做功能。
- 日志记录:可以记录命令的执行历史,方便后续的审计和调试。
缺点
- 类的数量增加:每个具体命令都需要一个对应的类,会导致类的数量增加,增加了系统的复杂性。
- 实现复杂:对于简单的操作,使用命令模式可能会增加代码的复杂度。