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日

相关文章

  • PHPExcel冻结(锁定)表头的简单实现方法

    针对您的问题,“PHPExcel冻结表头的简单实现方法”的完整攻略,我将给出以下的解释。 什么是PHPExcel PHPExcel 是一个 PHP 的电子表格处理库,它可以轻松地读写 Excel 格式的文件,并提供了许多高级功能,例如透视表,公式,图表等。通过 PHPExcel,我们可以使用 PHP 代码来访问 Excel 文件中的单元格、行和列数据,以及使…

    PHP 2023年5月26日
    00
  • php实现统计二进制中1的个数算法示例

    PHP实现统计二进制中1的个数算法示例 概述 在计算机中,二进制数是非常重要的概念。统计二进制中1的个数是一道经典的算法题目。在PHP语言中,实现这个算法是比较容易的,但是要理解这个算法的原理需要一定的数学知识。 算法原理 首先,我们需要了解二进制数的位运算。在二进制数中,常见的位运算符号有三种:按位与(&)、按位或(|)、按位异或(^)。在这些符号…

    PHP 2023年5月26日
    00
  • javascript中直接写php代码的方法

    首先,需要明确一点:JavaScript和PHP是两种完全不同的编程语言,不能直接在JavaScript中使用PHP代码。但是,有时候我们需要在JavaScript中与后台的PHP代码进行交互,比如获取PHP程序返回的数据。这种情况下,我们可以使用AJAX技术(Asynchronous JavaScript And XML,异步 JavaScript 和 X…

    PHP 2023年5月23日
    00
  • php仿ZOL分页类代码

    接下来我将为您详细讲解如何编写PHP仿ZOL分页类代码。 一、了解分页 为了更好地理解分页类的代码,我们首先需要了解分页是什么。分页是指将数据分割成多个部分进行显示,使得数据过多时可以分页展示,从而提高页面的加载速度,方便用户的查看。常见的分页方式有传统的数字翻页和类似于“下一页”、“上一页”的ajax异步加载。 二、开始写PHP仿ZOL分页类代码 1.建立…

    PHP 2023年5月30日
    00
  • PHP异步调用socket实现代码

    PHP异步调用socket实现是一种提高代码性能的方法,能够同时处理多个客户端请求,提高服务器的吞吐量。下面是实现这种方式的完整攻略: 一、安装需要的扩展 安装swoole扩展 pecl install swoole 安装event扩展 pecl install event 二、实现异步socket服务端 在服务端代码中,需要使用swoole与event两个…

    PHP 2023年5月23日
    00
  • php遍历数组的4种方法总结

    PHP遍历数组的4种方法总结 在PHP中,我们经常需要对数组进行操作,而遍历数组是常见的操作之一。本文将总结PHP中遍历数组的4种方法。 1. for循环遍历数组 for循环遍历数组是最基本的一种遍历方式,通过改变数组的下标来获取数组中的值。 $nums = [1, 2, 3, 4, 5]; for ($i = 0; $i < count($nums)…

    PHP 2023年5月25日
    00
  • PHP中一些可以替代正则表达式函数的字符串操作函数

    在PHP中,正则表达式函数是强大的,但是在一些简单的字符串操作中,使用正则表达式函数可能会带来性能损失。因此,PHP也提供了一些可以替代正则表达式函数的字符串操作函数。 1. strpos() strpos() 函数可以用来查找一个字符串中是否包含另一个字符串,如果包含则返回第一次出现的位置。例如,我们可以使用 strpos() 函数来检查一个字符串中是否包…

    PHP 2023年5月26日
    00
  • PHP flush()与ob_flush()的区别详解

    PHP flush()与ob_flush()的区别详解 在PHP中,使用输出缓冲技术可以将输出的内容暂时存放在内存中,从而方便对输出内容进行操作和控制。其中,flush()函数和ob_flush()函数都用于将缓冲区的内容立即输出。但是,它们具有略微不同的适用场景和效果。本文将详细讲解这两个函数的区别和使用方法。 1. flush()函数的用法和效果 flu…

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