若转载教程,请注明出自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.调用同一方法实现不同的功能
缺点
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
