命令模式 (Command Pattern): 將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使我們可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或者記錄請(qǐng)求日志,以及支持可撤銷的操作。命令模式是一種對(duì)象行為型模式,其別名為動(dòng)作(Action)模式或事務(wù)(Transaction)模式。
(一)為什么需要命令模式
1, 使用命令模式,能夠讓請(qǐng)求發(fā)送者與請(qǐng)求接收者消除彼此之間的耦合,讓對(duì)象之間的調(diào)用關(guān)系更加靈活。
2,使用命令模式可以比較容易地設(shè)計(jì)一個(gè)命令隊(duì)列和宏命令(組合命令),而且新的命令可以很容易地加入系統(tǒng)
(二)命令模式 UML圖

(三)簡(jiǎn)單實(shí)例
有關(guān)命令模式的一個(gè)經(jīng)典的例子,就是電視機(jī)與遙控器。如果按照命令模式的UML圖那么,就有這樣的對(duì)應(yīng)關(guān)系:電視機(jī)是請(qǐng)求的接收者,遙控器是請(qǐng)求的發(fā)送者。遙控器上有一些按鈕,不同的按鈕對(duì)應(yīng)電視機(jī)的不同操作。這些按鈕就是對(duì)應(yīng)的具體命令類。抽象命令角色由一個(gè)命令接口來(lái)扮演,有三個(gè)具體的命令類實(shí)現(xiàn)了抽象命令接口,這三個(gè)具體命令類分別代表三種操作:打開電視機(jī)、關(guān)閉電視機(jī)和切換頻道。
<?php
//抽象命令角色
abstract class Command{
protected $receiver;
function __construct(TV $receiver)
{
$this->receiver = $receiver;
}
abstract public function execute();
}
//具體命令角色 開機(jī)命令
class CommandOn extends Command
{
public function execute()
{
$this->receiver->action();
}
}
//具體命令角色 關(guān)機(jī)機(jī)命令
class CommandOff extends Command
{
public function execute()
{
$this->receiver->action();
}
}
//命令發(fā)送者 --遙控器
class Invoker
{
protected $command;
public function setCommand(Command $command)
{
$this->command = $command;
}
public function send()
{
$this->command->execute();
}
}
//命令接收者 Receiver =》 TV
class TV
{
public function action()
{
echo "接收到命令,執(zhí)行成功".PHP_EOL;
}
}
//實(shí)例化命令接收者 -------買一個(gè)電視機(jī)
$receiver = new TV();
//實(shí)例化命令發(fā)送者-------配一個(gè)遙控器
$invoker = new Invoker();
//實(shí)例化具體命令角色 -------設(shè)置遙控器按鍵匹配電視機(jī)
$commandOn = new CommandOn($receiver);
$commandOff = new CommandOff($receiver);
//設(shè)置命令 ----------按下開機(jī)按鈕
$invoker->setCommand($commandOn);
//發(fā)送命令
$invoker->send();
//設(shè)置命令 -----------按下關(guān)機(jī)按鈕
$invoker->setCommand($commandOff);
//發(fā)送命令
$invoker->send();
在實(shí)際使用中,命令模式的receiver經(jīng)常是一個(gè)抽象類,就是對(duì)于不同的命令,它都有對(duì)應(yīng)的具體命令接收者。命令模式的本質(zhì)是對(duì)命令進(jìn)行封裝,將發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分割開。