PHP设计模式之命令行模式(Command)代码实例大全(22)

目的

为了封装调用和解耦。

我们有一个调用程序和一个接收器。 这种模式使用「命令行」将方法调用委托给接收器并且呈现相同的「执行」方法。 因此,调用程序只知道调用「执行」去处理客户端的命令。接收器会从调用程序中分离出来。

这个模式的另一面是取消方法的 execute (),也就是 undo () 。命令行也可以通过最小量的复制粘贴和依赖组合(不是继承)被聚合,从而组合成更复杂的命令集。

例子

文本编辑器:所有事件都是可以被解除、堆放,保存的命令。

Symfony2:SF2 命令可以从 CLI 运行,它的建立只需考虑到命令行模式。

大型 CLI 工具使用子程序来分发不同的任务并将它们封装在「模型」中,每个模块都可以通过命令行模式实现(例如:vagrant)。

UML图

PHP设计模式之命令行模式(Command)代码实例大全(22)

★官方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进阶教程,全系列!

PHP设计模式之命令行模式(Command)代码实例大全(22)

内容不错的话希望大家支持鼓励下点个赞/喜欢,欢迎一起来交流;另外如果有什么问题 建议 想看的内容可以在评论提出

PHP设计模式之命令行模式(Command)代码实例大全(22)

上一篇:jQuery - 遍历(七)


下一篇:批量部署前端Node.js守护forever