若转载教程,请注明出自SW-X框架官方文档!
<?php
/**
* 设计模式之命令模式
* 模拟场景:
* 1、在古代,皇帝是最喜欢下达命令的角色,并且皇宫重地,除了皇子与护卫之外,就不能有其他的男人,
* 所以每次下达命令时,皇上不可能将所有部门重臣都召唤到跟前,这个时候就需要有一个能够传达命令的角色。
* 2、在古代,这个传递命令的角色很出名,他就是太监,太监并没有任何权力,但当他拿到命令时,便可以调派命令所对应的部门角色。
* 3、假设皇上想派兵攻打岛国,让厨房做个早点这个时候就需要2个部门角色了。
* 4、并且太监是需要调派命令的权力,这时我们设计一个接口,用于把每个命令具体化,不然太监也不知道自己该去调派什么命令。
* 小黄牛
*/
header("Content-type: text/html; charset=utf-8");
/**
* 接口 命令类
*/
interface Initiator{
public function Command(); // 抽象出一个普通命令接口
}
/**
* 写张圣旨 - 皇上要打鬼子了
*/
class DaZhang implements Initiator{
public function Command(){
echo '快去给我削了那帮鬼子!<br/>';
}
}
/**
* 写张圣旨 - 皇上要吃饭
*/
class ChiFan implements Initiator{
public function Command(){
echo '给朕准备两桌好菜!<br/>';
}
}
/**
* 抽象 部门类
*/
abstract class Command{
public $name; // 部门名称
protected $Initiator; // 命令的实例
public function execute(){} // 抽象一个方法,所有部门都必须实现,用于执行命名
}
/**
* 创建 - 兵部
*/
class BingBu extends Command{
public function __construct($Initiator){
$this->name = '兵部';
$this->Initiator = $Initiator; // 接圣旨
}
public function execute(){
$this->Initiator->Command();
}
}
/**
* 创建 - 御膳房
*/
class ChuFang extends Command{
public function __construct($Initiator){
$this->name = '御膳房';
$this->Initiator = $Initiator; // 接圣旨
}
public function execute(){
$this->Initiator->Command();
}
}
/**
* 抽象 对接类
*/
abstract class Pickup{
public $name; // 对接人名称
protected $Initiator; // 部门的实例,你得告诉对接人要去哪里,并且对接人不该拥有任何操作命令的权限,防止中途被修改
public function run_errands(){} // 抽象一个方法,对接人需要使用这个方法去发送命令
}
/**
* 创建一个对接人 - 太监小李子
*/
class TaiJian extends Pickup{
public function __construct($Command){
$this->name = '东厂- 小李子';
$this->Command = $Command; // 接到部门地址
}
# 去传递命令咯
public function run_errands(){
echo $this->name . ',奉天承运:';
$this->Command->execute();
echo $this->Command->name . ',领旨!<br/>';
}
}
/**
* 创建一个发起人 - 皇上
*/
class HuangShang{
public function Go(){
# 让小李子去兵部
$tj1 = new Taijian(new BingBu(new DaZhang()));
$tj1->run_errands();
# 让小李子去御膳房
$tj2 = new Taijian(new Chufang(new ChiFan()));
$tj2->run_errands();
}
}
$res= new HuangShang();
$res->Go();
浏览器输出
东厂- 小李子,奉天承运:快去给我削了那帮鬼子!
兵部,领旨!
东厂- 小李子,奉天承运:给朕准备两桌好菜!
御膳房,领旨!
命令模式
抽象命令(Initiator),定义命令的接口,声明执行的方法。
具体命令(XInitiator),将需要执行的命令实现化;
抽象接收者(Command),声明接受者自身,并接纳命令实例,并定义一个方法,使用部门都应该在执行命令后给予上级回复。
具体接收者(XCommand),将接收者具体化。
抽象持有者(Pickup),这个角色相当于跑腿,它持有命令的制定到达地点,但却不能持有该命令的实例,以防止持有者在中途将命令修改。
具体持有者(XPickup),将持有者具体化。
控制者(DIY):创建命令对象,并让持有者到达指定接受者处传达 命令。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
使用场景
1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。
优点
1.降低对象之间的耦合度。
2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
4.调用同一方法实现不同的功能
缺点
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。