設計模式之命令模式–php實現命令模式
命令模式
就是把命令封裝成對象。
將一個請求封裝爲對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄日誌,以及支持可撤銷的操作。
爲什麼要使用命令模式
命令模式有哪些好處呢?
- 他能較容易的設計一個命令隊列
- 在需要的情況下,可以較容易的將命令寫入日誌
- 允許接受請求的一方決定是否要否決請求
- 可以容易的實現對請求的撤銷和重做
- 加入新的命令類更加容易
命令模式把請求一個操作的對象和直到怎麼執行一個操作的對象分隔開。
比如服務員
把操作的請求者客戶
和操作的執行者廚師
分離開,把客戶的命令
傳遞給廚師。
- 並可以傳遞一系列命令
- 可以把命令記錄下來
- 可以說這個菜沒有了否決請求
- 可以客戶不要菜了撤銷請求
- 可以加入新的菜品命令
比如自如管家
把操作的請求者租戶
和操作的執行者房東
分離開,把租戶的需求
傳遞給房東。
- 可以傳遞一系列需求,比如要修電視,修洗衣機
- 可以把命令記錄下來,然後一起告訴房東
- 可以說這個不在服務範圍內
- 可以租戶修好了,說不用修了
- 可以加入新的需求命令
當然這個比喻不太準確,哈哈哈,自如更像中介模式
把所有的房東和租戶分離開。
php實現命令模式
我們先找到一個房東,房東類可以修電視,修洗衣機
/**
* 命令模式
* 房東類,提供修洗衣機修電視服務
*/
class receiver {
/**
* 修電視
*/
public function TV() {
dump('房東修電視');
}
/**
* 修洗衣機
*/
public function wash() {
dump('房東修洗衣機');
}
}
有了房東我們接下來找一個自如管家,讓管家聯繫房東。
/**
* 命令模式
* 自如管家,負責接收命令傳遞給房東
*/
class invoke {
private $arr = [];
/**
* 設置命令
*/
public function setCommand(Command $command) {
$this->arr[] = $command;
}
/**
* 撤銷命令
*/
public function cancel(Command $command) {
foreach($this->arr as $key => $com) {
if ($com == $command) {
unset($this->arr[$key]);
}
}
}
/**
* 執行命令
*/
public function exec() {
foreach($this->arr as $command) {
$command->exec();
}
}
}
我們現在可以像管家下命令了,哎,沒有命令類啊,那我們現在增加命令。
/**
* 命令模式
* 命令抽象類,所有具體命令繼承這個類
*/
abstract class Command {
protected $receiver;
/**
* 創建命令的時候要告訴這個命令是給誰執行的,所以要傳入執行者
*/
public function __construct(receiver $receiver) {
$this->receiver = $receiver;
}
public abstract function exec();
}
/**
* 命令模式
* 修電視命令
*/
class tv extends Command{
/**
* 把命令告訴真正的執行者
* 讓執行者修電視
*/
public function exec() {
$this->receiver->tv();
}
}
/**
* 命令模式
* 修洗衣機命令
*/
class wash extends Command{
/**
* 把命令告訴真正的執行者
* 讓執行者修洗衣機
*/
public function exec() {
$this->receiver->wash();
}
}
好了,有了命令,我們可以給管家下命令了。
$invoke = new invoke();
//租戶告訴管家找房東修電視
$invoke->setCommand(new tv(new receiver));
//租戶告訴管家找房東修洗衣機
$invoke->setCommand(new wash(new receiver));
//管家找房東去了
$invoke->exec();
這就是命令模式,不過在程序中,我還沒想好有啥場景使用這個模式。。。
代碼放在了我的github上面。