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

yizhihongxing

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截取html字符串及自动补全html标签的方法

    PHP截取HTML字符串方法 在PHP中,我们可以使用DOMDocument类来解析HTML文档,并且可以使用XPath查询语言来定位HTML元素。 下面是一个示例,演示如何使用DOMDocument类来截取HTML字符串: // 要截取的HTML字符串 $html = ‘<div class="content"> <h…

    PHP 2023年5月26日
    00
  • Android AsyncTack 异步任务实例详解

    Android AsyncTack 异步任务实例详解 什么是AsyncTask Android AsyncTask是一个Android轻量级异步处理类,它能够帮助开发者更加方便的实现异步处理,而不需要借助复杂的线程操作。 基本上,在Android开发中使用AsyncTask比使用直接线程的方式更加方便和直观。AsyncTask可以在后台线程上执行操作,然后发…

    PHP 2023年5月27日
    00
  • 学习php分页代码实例

    学习 PHP 分页代码实例的完整攻略如下: 1. 了解分页的概念 分页是指将一个大数据集合分成多个部分进行展示的过程。在网站开发中,常常用到分页功能来避免大量数据在一次性进行呈现时导致页面加载缓慢或者崩溃的问题。 2. 确定需要使用的分页方案 在 PHP 中,实现分页的方式有很多,例如使用 SQL 中的 LIMIT 语句、利用数组的 array_slice …

    PHP 2023年5月23日
    00
  • PHP中文字符串截断无乱码解决方法

    PHP中文字符串截断时常常出现乱码问题,这主要是因为PHP默认使用的是ASCII编码,而中文字符占用多个字节,导致截断时出现了断裂和乱码。下面是一些解决方法。 方法一:使用mb_substr函数 mb_substr函数是php中用于截取多字节字符串的函数,在使用时指定字符串长度和编码,就可以避免出现乱码了。示例代码如下: $str = "我是一名P…

    PHP 2023年5月26日
    00
  • PHP中isset()和unset()函数的用法小结

    来详细讲解一下“PHP中isset()和unset()函数的用法小结”。 isset()函数的用法 在 PHP 中,我们可以使用 isset() 函数来判断一个变量是否已经被声明和赋值。该函数接收待测试的变量作为参数,返回一个布尔值 true 或 false,表明该变量是否被设置。 isset()函数的语法 isset($var); 其中 $var 是要检测…

    PHP 2023年5月26日
    00
  • 微信小程序动态显示项目倒计时效果

    要实现微信小程序动态显示项目倒计时效果,首先需要了解如何使用小程序API和JavaScript实现计时器功能。 第一步:获取倒计时时间 需要在小程序页面中定义一个变量,用于存储倒计时的总时间,例如: var totalSeconds = 300; // 倒计时总秒数,这里是5分钟,可以根据需求进行设置 第二步:设置计时器 使用setInterval函数来定时…

    PHP 2023年5月23日
    00
  • MySql数据库查询结果用表格输出PHP代码示例

    下面给出详细讲解”MySql数据库查询结果用表格输出PHP代码示例”的完整攻略。该攻略包含以下步骤: 连接数据库 使用PHP连接到MySql数据库,获取数据库连接对象。示例代码如下: // 连接数据库 $conn = mysqli_connect($servername, $username, $password, $dbname); if (!$conn)…

    PHP 2023年5月26日
    00
  • 常用照片尺寸有哪几个? 照片标准尺寸/像素对照表汇总

    在设计和处理照片时,了解常用的照片尺寸和像素大小是非常重要的。以下是常用照片尺寸和像素大小的汇总说明: 照片标准尺寸/像素对照表汇总 1. 网络图片 头像:一般为方形,在 200200 像素到500500 像素之间。 banner:网站首页的大图,通常是横幅广告。可以根据网站设计自由调整大小,多为 1920*1080 像素或更大。 2. 社交媒体 FaceB…

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