PHP設計模式之命令行模式(Command)代碼實例大全(22)

目的

爲了封裝調用和解耦。php

咱們有一個調用程序和一個接收器。 這種模式使用「命令行」將方法調用委託給接收器而且呈現相同的「執行」方法。 所以,調用程序只知道調用「執行」去處理客戶端的命令。接收器會從調用程序中分離出來。laravel

這個模式的另外一面是取消方法的 execute (),也就是 undo () 。命令行也能夠經過最小量的複製粘貼和依賴組合(不是繼承)被聚合,從而組合成更復雜的命令集。面試

例子

文本編輯器:全部事件都是能夠被解除、堆放,保存的命令。sql

Symfony2:SF2 命令能夠從 CLI 運行,它的創建只需考慮到命令行模式。shell

大型 CLI 工具使用子程序來分發不一樣的任務並將它們封裝在「模型」中,每一個模塊均可以經過命令行模式實現(例如:vagrant)。設計模式

UML圖

★官方PHP高級學習交流社羣「點擊」管理整理了一些資料,BAT等一線大廠進階知識體系備好(相關學習資料以及筆面試題)以及不限於:分佈式架構、高可擴展、高性能、高併發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨服務器

代碼

  • 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 互聯網架構師成長之路*「設計模式」終極指南架構

PHP 互聯網架構師 50K 成長指南+行業問題解決總綱(持續更新)併發

面試10家公司,收穫9個offer,2020年PHP 面試問題編輯器

★若是喜歡個人文章,想與更多資深開發者一塊兒交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入咱們的羣啊,暗號:phpzh(君羊號碼856460874)。

2020年最新PHP進階教程,全系列!

內容不錯的話但願你們支持鼓勵下點個贊/喜歡,歡迎一塊兒來交流;另外若是有什麼問題 建議 想看的內容能夠在評論提出

相關文章
相關標籤/搜索