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技术站