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

内容不错的话但愿你们支持鼓励下点个赞/喜欢,欢迎一块儿来交流;另外若是有什么问题 建议 想看的内容能够在评论提出

相关文章
相关标签/搜索