PHP设计模式之命令模式示例详解

PHP设计模式之命令模式示例详解

命令模式是一种行为型模式,它允许你将请求封装成对象,这样就可以使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持撤销操作,因此被称为可撤销的操作。

示例1: 使用命令模式实现固定长度的文件备份

示例1中,我们将使用命令模式实现固定长度的文件备份。在此示例中,我们将使用一个Command接口来表示备份的命令,并让每个具体的备份命令实现这个接口。在备份管理器中,我们将存储备份命令,并通过管理器执行它们。以下是示例代码:

Command接口

interface Command
{
    public function execute(): void;
}

两种备份命令

// 备份命令1:保存文件前100行
class BackupCommand1 implements Command
{
    private $filename;

    public function __construct($filename)
    {
        $this->filename = $filename;
    }

    public function execute(): void
    {
        $lines = file($this->filename);
        array_splice($lines, 100);
        file_put_contents($this->filename, implode('', $lines));
        echo "备份文件成功!\n";
    }
}

// 备份命令2:保存文件后100行
class BackupCommand2 implements Command
{
    private $filename;

    public function __construct($filename)
    {
        $this->filename = $filename;
    }

    public function execute(): void
    {
        $lines = file($this->filename);
        array_splice($lines, 0, -100);
        file_put_contents($this->filename, implode('', $lines));
        echo "备份文件成功!\n";
    }
}

备份管理器

class BackupManager
{
    private $commands = [];

    public function addCommand(Command $command): void
    {
        $this->commands[] = $command;
    }

    public function executeCommands(): void
    {
        foreach ($this->commands as $command) {
            $command->execute();
        }
    }
}

使用备份管理器

$backupManager = new BackupManager();

// 添加备份命令1
$backupManager->addCommand(new BackupCommand1('/path/to/your/file'));

// 添加备份命令2
$backupManager->addCommand(new BackupCommand2('/path/to/your/file'));

// 执行备份
$backupManager->executeCommands();

在上述示例中,我们创建了两个备份命令,一个保存文件前100行,另一个保存文件后100行。我们使用备份管理器来保存备份命令,并最后执行这些命令。运行示例代码时,你会发现文件已经备份完成,且只保存了前100行或后100行。

示例2: 使用命令模式实现撤销和重做功能

示例2中,我们将再次使用命令模式,这次是为了实现撤销和重做功能。我们将使用一个Command接口以及具体的命令类来表示操作,而撤销和重做功能将由Invoker类处理。以下是示例代码:

Command接口和其具体命令类

interface Command
{
    public function execute(): void;

    public function undo(): void;
}

// 具体的命令类,增加数字
class AddCommand implements Command
{
    private $receiver;

    private $number;

    public function __construct(Receiver $receiver, $number)
    {
        $this->receiver = $receiver;
        $this->number = $number;
    }

    public function execute(): void
    {
        $this->receiver->add($this->number);
    }

    public function undo(): void
    {
        $this->receiver->subtract($this->number);
    }
}

// 具体的命令类,减少数字
class SubtractCommand implements Command
{
    private $receiver;

    private $number;

    public function __construct(Receiver $receiver, $number)
    {
        $this->receiver = $receiver;
        $this->number = $number;
    }

    public function execute(): void
    {
        $this->receiver->subtract($this->number);
    }

    public function undo(): void
    {
        $this->receiver->add($this->number);
    }
}

执行者类

class Receiver
{
    public $number;

    public function __construct()
    {
        $this->number = 0;
    }

    public function add($number): void
    {
        $this->number += $number;
        echo "增加了 $number ,当前数字为 {$this->number}\n";
    }

    public function subtract($number): void
    {
        $this->number -= $number;
        echo "减少了 $number ,当前数字为 {$this->number}\n";
    }
}

Invoker类

class Invoker
{
    private $commands = [];

    private $pointer = 0;

    public function addCommand(Command $command): void
    {
        array_splice($this->commands, $this->pointer);
        $this->pointer = count($this->commands);
        $this->commands[] = $command;
        $command->execute();
    }

    public function undo(): void
    {
        if ($this->pointer === 0) {
            return;
        }

        $command = $this->commands[--$this->pointer];
        $command->undo();
    }

    public function redo(): void
    {
        if ($this->pointer === count($this->commands)) {
            return;
        }

        $command = $this->commands[$this->pointer++];
        $command->execute();
    }
}

使用Invoker类实现撤销/重做

// 创建执行者和命令对象
$receiver = new Receiver();

$addCommand = new AddCommand($receiver, 5);
$subCommand = new SubtractCommand($receiver, 10);

// 创建Invoker对象
$invoker = new Invoker();

// 执行命令
$invoker->addCommand($addCommand);
$invoker->addCommand($subCommand);
$invoker->addCommand($addCommand);

// 撤销和重做
$invoker->undo();
$invoker->undo();
$invoker->redo();
$invoker->redo();

在此示例中,我们使用Invoker类来保存命令对象,并根据用户的使用来执行、撤销和重做。每次执行命令时,我们先将其保存在Invoker中,并执行它。撤销和重做则由Invoker类内部实现。运行示例代码时,可以看到数字被增加,减少,然后又增加,最后进行撤销和重做操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:PHP设计模式之命令模式示例详解 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 详解PHP中foreach的用法和实例

    当我们需要遍历一个数组或对象中的元素时,foreach循环结构就非常有用了。为了帮助更多的开发人员掌握foreach的用法,本篇攻略详解了PHP中foreach的用法和实例。 1. foreach的基本语法 foreach语法的基本格式如下: foreach (array_expression as $value) { statement } 其中,arra…

    PHP 2023年5月23日
    00
  • PHP程序员必须知道的两种日志实例分析

    当 PHP 应用程序出现故障或效率低下时,日志记录是一种诊断问题的常见方法。在 PHP 应用程序中,可以使用两种不同的日志记录方式来分析问题 – 请求级别和应用程序级别的日志记录。以下是 PHP 程序员必须知道的这两种日志实例分析的完整攻略: 请求级别的日志记录 请求级别的日志记录在每个请求期间记录请求和响应的详细信息。这些日志由 web 服务器的访问日志和…

    PHP 2023年5月23日
    00
  • php中利用explode函数分割字符串到数组

    针对“php中利用explode函数分割字符串到数组”的问题,我给出以下的完整攻略。 1. explode函数定义 explode() 函数可以将一个字符串,按照指定分隔符分割成多个字符串,并将分割后的字符串存放在一个数组中。 该函数的基本语法如下: explode(string $separator, string $string [, int $limi…

    PHP 2023年5月26日
    00
  • 小程序通过小程序云实现微信支付功能实例

    小程序通过小程序云实现微信支付功能需要以下几个步骤: 注册并开通微信支付功能首先需要在微信支付开放平台注册账号,并按照微信支付文档的要求,完成商户信息的填写和资质证明的上传。然后开通微信支付功能,获取到商户ID(即mch_id)和API密钥(即api_key)等重要参数,这些参数后续会在小程序中用到。 在小程序中配置支付接口接下来需要在小程序管理后台中,进入…

    PHP 2023年5月30日
    00
  • linux编辑文件保存退出的实操讲解

    关于“Linux编辑文件保存退出的实操讲解”的攻略,我将从以下几个方面进行详细讲解: Linux编辑器介绍 编辑文件的基本操作 保存文件和退出编辑器的方法 1. Linux编辑器介绍 Linux编辑器是一种用于编辑、查看和修改文本文件的工具,它根据用户的需要提供了多种编辑方式和功能,在Linux操作系统中使用频率非常高。目前,常见的Linux编辑器有Vim、…

    PHP 2023年5月27日
    00
  • 微信小程序如何获取用户手机号

    微信小程序可以使用手机号作为用户的唯一标识,可以通过微信提供的API获取用户的手机号,具体操作步骤如下: 1. 开启微信用户手机号授权 在小程序的app.json文件中,设置如下选项,表示开启用户手机号授权功能: { "permission": { "scope.userLocation": { "desc&…

    PHP 2023年5月23日
    00
  • 微信小程序实现图片放大预览功能

    下面是“微信小程序实现图片放大预览功能”的完整攻略: 1. 使用自带组件<image>展示图片 我们可以使用小程序自带的<image>组件来展示图片,示例代码如下: <image src="{{imageUrl}}"></image> 其中imageUrl为图片的网络链接或本地临时文件路径。…

    PHP 2023年5月23日
    00
  • php生成静态文件的多种方法分享

    PHP生成静态文件的多种方法分享 在网站开发中,动态网页的加载速度可能会受到网络、服务器等因素的影响而变得较慢,尤其在高并发情况下,这可能会导致用户的不满,甚至影响网站的使用体验。因此,生成静态文件并使用静态文件来增强网站的访问速度、减轻服务器压力是非常有必要的。现在,我们就来分享一下用PHP生成静态文件的几种方法。 方法一:使用file_put_conte…

    PHP 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部