命令模式又称为:动作、事务、Action、Transaction、Command。命令是一种行为设计模式,可将请求转换为一个包含与请求相关的所有信息的独立对象。该转换让你能根据不同的请求将方法参数化、延迟请求执行或将其放入队列中,且能实现可撤销操作。
大家肯定经常是用命令的,命令一敲,啥都不爱,这个笑话大家肯定看过:
这样一操作,你可能离包吃包住不远了,那么我们有没有一种办法可以在命令生效前,可撤销之前输入的命令呢?
比如我们常用的 ORM 模型,ORM 一旦发送命令给你数据库,那我们的数据永远找不回了。
其实我们可以在 客户端 和 命令执行者 中间添加一个中间人 命令发送者,命令发送者负责 接收客户端命令 和 发送命令,所有要执行的命令都在 命令发送者 里,可支持:撤回、重写、更新,这样的设计模式我们称为“命令模式”。
命令模式就和名字一样,比较适合执行命令,命令发送者只管调用具体命令类中的 execute() 方法,然后在具体命令类中设定命令接收者,可以消除命令发送者和命令接受者之间的耦合,并且可以方便的扩展新命令;
流程:先将命令注册到命令执行者中,再将需要执行的命令(如:Create、Update、Delete)发给 命令发送者 , 命令发送者 命令类中的 execute() 方法发送命令执行。
Command:命令抽象类;一般会暴露一个 execute 方法; Delete、Create、Update:具体的命令类;设定接收者; Invoker:命令发送者;用于调用命令; Model: 命令接收者;负责执行操作;
/**
* 命令模式接口基类
*/
abstract class Command
{
/**
* 模型
* @var Model
*/
public Model $model;
/**
* 命令名称
* @var
*/
public $name;
/**
* 执行方法
* @return mixed
* @author chendashengpc
*/
abstract public function execute();
}
PHP
Copy
删除
/**
* 删除
*/
class Delete extends Command
{
/**
* 初始化函数
* @param Model $model
*/
public function __construct(Model $model)
{
$this->name = 'delete';
$this->model = $model;
}
/**
* 执行函数
* @return mixed|void
* @author chendashengpc
*/
public function execute()
{
return $this->model->delete();
}
}
PHP
Copy
新增
/**
* 创建
*/
class Create extends Command
{
/**
* 初始化函数
* @param Model $model
*/
public function __construct(Model $model)
{
$this->name = 'create';
$this->model = $model;
}
/**
* 执行函数
* @return mixed|void
* @author chendashengpc
*/
public function execute()
{
return $this->model->create();
}
PHP
Copy
更新
/**
* 更新
*/
class Update extends Command
{
/**
* 初始化函数
* @param Model $model
*/
public function __construct(Model $model)
{
$this->name = 'update';
$this->model = $model;
}
/**
* 执行函数
* @return mixed|void
* @author chendashengpc
*/
public function execute()
{
return $this->model->update();
}
}
PHP
Copy
/**
* 调用类
*/
class Invoker
{
protected $command = [];
/**
* 设置命令
* @param Command $command
* @return void
* @author chendashengpc
*/
public function setCommand(Command $command)
{
$this->command[$command->name] = $command;
}
/**
* 撤销命令
* @return void
* @author chendashengpc
*/
public function revoke(Command $command)
{
if (isset($this->command[$command->name])) {
unset($this->command[$command->name]);
}
}
/**
* 执行命令
* @return void
* @author chendashengpc
*/
public function execute()
{
foreach ($this->command as $command) {
echo $command->execute() . PHP_EOL;
}
}
}
PHP
Copy
/**
* 具体接受者类(Model类)
*/
class Model
{
/**
* 删除
* @return void
* @author chendashengpc
*/
public function delete()
{
return '删除命令';
}
/**
* 更新
* @return void
* @author chendashengpc
*/
public function update()
{
return '更新命令';
}
/**
* 新增
* @return string
* @author chendashengpc
*/
public function create()
{
return '新增命令';
}
}
PHP
Copy
// 新建一个模型
$model = new Model();
$create = new Create($model);
$update = new Update($model);
$delete = new Delete($model);
// 设置一个调用者
$invoker = new Invoker();
$invoker->setCommand($create);
$invoker->setCommand($update);
$invoker->setCommand($delete);
$invoker->revoke($delete);
$invoker->execute();
PHP
Copy
输出
新增命令
更新命令