PHP設計模式之命令列模式(Command)程式碼例項大全(22)
阿新 • • 發佈:2020-09-17
目的
為了封裝呼叫和解耦。
我們有一個呼叫程式和一個接收器。 這種模式使用「命令列」將方法呼叫委託給接收器並且呈現相同的「執行」方法。 因此,呼叫程式只知道呼叫「執行」去處理客戶端的命令。接收器會從呼叫程式中分離出來。
這個模式的另一面是取消方法的 execute (),也就是 undo () 。命令列也可以通過最小量的複製貼上和依賴組合(不是繼承)被聚合,從而組合成更復雜的命令集。
例子
文字編輯器:所有事件都是可以被解除、堆放,儲存的命令。
Symfony2:SF2 命令可以從 CLI 執行,它的建立只需考慮到命令列模式。
大型 CLI 工具使用子程式來分發不同的任務並將它們封裝在「模型」中,每個模組都可以通過命令列模式實現(例如:vagrant)。
UML圖
程式碼
- CommandInterface.php
<?php namespace DesignPatterns\Behavioral\Command; interface CommandInterface { /** * 這是在命令列模式中很重要的方法, * 這個接收者會被載入構造器 */ public function execute(); }
- HelloCommand.php
<?php namespace DesignPatterns\Behavioral\Command; /** * 這個具體命令,在接收器上呼叫 "print" , * 但是外部呼叫者只知道,這個是否可以執行。 */ class HelloCommand implements CommandInterface { /** * @var Receiver */ private $output; /** * 每個具體的命令都來自於不同的接收者。 * 這個可以是一個或者多個接收者,但是引數裡必須是可以被執行的命令。 * * @param Receiver $console */ public function __construct(Receiver $console) { $this->output = $console; } /** * 執行和輸出 "Hello World". */ public function execute() { // 有時候,這裡沒有接收者,並且這個命令執行所有工作。 $this->output->write('Hello World'); } }
- Receiver.php
<?php
namespace DesignPatterns\Behavioral\Command;
/**
* 接收方是特定的服務,有自己的 contract ,只能是具體的例項。
*/
class Receiver
{
/**
* @var bool
*/
private $enableDate = false;
/**
* @var string[]
*/
private $output = [];
/**
* @param string $str
*/
public function write(string $str)
{
if ($this->enableDate) {
$str .= ' ['.date('Y-m-d').']';
}
$this->output[] = $str;
}
public function getOutput(): string
{
return join("\n", $this->output);
}
/**
* 可以顯示訊息的時間
*/
public function enableDate()
{
$this->enableDate = true;
}
/**
* 禁止顯示訊息的時間
*/
public function disableDate()
{
$this->enableDate = false;
}
}
- Invoker.php
<?php
namespace DesignPatterns\Behavioral\Command;
/**
*呼叫者使用這種命令。
* 比例 : 一個在 SF2 中的應用
*/
class Invoker
{
/**
* @var CommandInterface
*/
private $command;
/**
* 在這種呼叫者中,我們發現,訂閱命令也是這種方法
* 還包括:堆疊、列表、集合等等
*
* @param CommandInterface $cmd
*/
public function setCommand(CommandInterface $cmd)
{
$this->command = $cmd;
}
/**
* 執行這個命令;
* 呼叫者也是用這個命令。
*/
public function run()
{
$this->command->execute();
}
}
測試
- Tests/CommandTest.php
<?php
namespace DesignPatterns\Behavioral\Command\Tests;
use DesignPatterns\Behavioral\Command\HelloCommand;
use DesignPatterns\Behavioral\Command\Invoker;
use DesignPatterns\Behavioral\Command\Receiver;
use PHPUnit\Framework\TestCase;
class CommandTest extends TestCase
{
public function testInvocation()
{
$invoker = new Invoker();
$receiver = new Receiver();
$invoker->setCommand(new HelloCommand($receiver));
$invoker->run();
$this->assertEquals('Hello World', $receiver->getOutput());
}
}
PHP 網際網路架構師 50K 成長指南+行業問題解決總綱(持續更新)
面試10家公司,收穫9個offer,2020年PHP 面試問題
★如果喜歡我的文章,想與更多資深開發者一起交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入我們的群啊,暗號:phpzh(君羊號碼856460874)。
內容不錯的話希望大家支援鼓勵下點個贊/喜歡,歡迎一起來交流;另外如果有什麼問題 建議 想看的內容可以在評論提出