学习php设计模式 php实现命令模式(command)


Posted in PHP onDecember 08, 2015

一、意图
将一个请求封装为一个对象,从而使用你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
可变的方面是:何时,怎样满足一个请求
命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。
请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
二、命令模式结构图

学习php设计模式 php实现命令模式(command) 

三、命令模式中主要角色
命令(Command)角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色。
具体命令(ConcreteCommand)角色:定义一个接受者和行为之间的弱耦合;实现Execute()方法,负责调用接收考的相应操作。Execute()方法通常叫做执行方法。
客户(Client)角色:创建了一个具体命令(ConcreteCommand)对象并确定其接收者。
请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
四、命令模式的优点
命令模式的优点:
1、命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分离开。
2、命令类与其他任何别的类一样,可以修改和推广。
3、可以把命令对象聚合在一起,合成为合成命令。
4、可以很容易的加入新的命令类。
命令模式的缺点:可能会导致某些系统有过多的具体命令类。
五、命令模式适用场景
1、抽象出待执行的动作以参数化对象。Command模式是回调机制的一个面向对象的替代品。
2、在不同的时刻指定、排列和执行请求。
3、支持取消操作。
4、支持修改日志。
5、用构建在原语操作上的高层操作构造一个系统。Command模式提供了对事务进行建模的方法。Command有一个公共的接口,使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
六、命令模式与其它模式
合成模式(composite模式):Composite模式可被实现宏命令
原型模式(prototype模式):如果命令类带有clone(或在之前的文章中提到的copy方法)方法,命令就可以被复制。在命令模式支持多次取消操作时可能需要用到此模式,以复制当前状态的Command对象
七、命令模式PHP示例

<?php
/**
 * 命令角色
 */
interface Command {
 
  /**
   * 执行方法
   */
  public function execute();
}
 
/**
 * 具体命令角色
 */
class ConcreteCommand implements Command {
 
  private $_receiver;
 
  public function __construct(Receiver $receiver) {
    $this->_receiver = $receiver;
  }
 
  /**
   * 执行方法
   */
  public function execute() {
    $this->_receiver->action();
  }
}
 
/**
 * 接收者角色
 */
class Receiver {
 
  /* 接收者名称 */
  private $_name;
 
  public function __construct($name) {
    $this->_name = $name;
  }
 
  /**
   * 行动方法
   */
  public function action() {
    echo $this->_name, ' do action.<br />';
  }
}
 
/**
 * 请求者角色
 */
class Invoker {
 
  private $_command;
 
  public function __construct(Command $command) {
    $this->_command = $command;
  }
 
  public function action() {
    $this->_command->execute();
  }
}
 
/**
 * 客户端
 */
class Client {
 
   /**
   * Main program.
   */
  public static function main() {
    $receiver = new Receiver('phpppan');
    $command = new ConcreteCommand($receiver);
    $invoker = new Invoker($command);
    $invoker->action();
  }
}
 
Client::main();
 
?>

八、命令模式协作
1、Client创建一个ConcreteCommand对象并指定它的Receiver对象
2、某Invoker对象存储该ConcreteCommand对象
3、该Invoker通过调用Command对象的execute操作来提交一个请求。若该命令是可撤消的,ConcreteCommand就在执行execute操作之前存储当前状态以用于取消命令。
4、ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求。
九、宏命令
在这里,我们以一个简单的增加和粘贴功能为例,将这两个命令组成一个宏命令。
我们可以新建复制命令和粘贴命令,然后将其添加到宏命令中去。
如下所示代码:

<?php
/**
 * 命令角色
 */
interface Command {
 
  /**
   * 执行方法
   */
  public function execute();
}
 
/**
 * 宏命令接口
 */
interface MacroCommand extends Command {
 
  /**
   * 宏命令聚集的管理方法,可以删除一个成员命令
   * @param Command $command
   */
  public function remove(Command $command);
 
  /**
   * 宏命令聚集的管理方法,可以增加一个成员命令
   * @param Command $command
   */
  public function add(Command $command);
 
}
 
 
class DemoMacroCommand implements MacroCommand {
 
  private $_commandList;
 
  public function __construct() {
    $this->_commandList = array();
  }
 
  public function remove(Command $command) {
    $key = array_search($command, $this->_commandList);
    if ($key === FALSE) {
      return FALSE;
    }
 
    unset($this->_commandList[$key]);
    return TRUE;
  }
 
  public function add(Command $command) {
    return array_push($this->_commandList, $command);
  }
 
  public function execute() {
    foreach ($this->_commandList as $command) {
      $command->execute();
    }
 
  }
 
}
 
/**
 * 具体拷贝命令角色
 */
class CopyCommand implements Command {
 
  private $_receiver;
 
  public function __construct(Receiver $receiver) {
    $this->_receiver = $receiver;
  }
 
  /**
   * 执行方法
   */
  public function execute() {
    $this->_receiver->copy();
  }
}
 
/**
 * 具体拷贝命令角色
 */
class PasteCommand implements Command {
 
  private $_receiver;
 
  public function __construct(Receiver $receiver) {
    $this->_receiver = $receiver;
  }
 
  /**
   * 执行方法
   */
  public function execute() {
    $this->_receiver->paste();
  }
}
 
/**
 * 接收者角色
 */
class Receiver {
 
  /* 接收者名称 */
  private $_name;
 
  public function __construct($name) {
    $this->_name = $name;
  }
 
  /**
   * 复制方法
   */
  public function copy() {
    echo $this->_name, ' do copy action.<br />';
  }
 
  /**
   * 粘贴方法
   */
  public function paste() {
    echo $this->_name, ' do paste action.<br />';
  }
}
 
/**
 * 请求者角色
 */
class Invoker {
 
  private $_command;
 
  public function __construct(Command $command) {
    $this->_command = $command;
  }
 
  public function action() {
    $this->_command->execute();
  }
}
 
/**
 * 客户端
 */
class Client {
 
   /**
   * Main program.
   */
  public static function main() {
    $receiver = new Receiver('phpppan');
    $pasteCommand = new PasteCommand($receiver);
    $copyCommand = new CopyCommand($receiver);
 
    $macroCommand = new DemoMacroCommand();
    $macroCommand->add($copyCommand);
    $macroCommand->add($pasteCommand);
 
    $invoker = new Invoker($macroCommand);
    $invoker->action();
 
    $macroCommand->remove($copyCommand);
    $invoker = new Invoker($macroCommand);
    $invoker->action();
  }
}
 
Client::main();
 
 
?>

以上就是使用php实现命令模式的代码,还有一些关于命令模式的概念区分,希望对大家的学习有所帮助。

PHP 相关文章推荐
定制404错误页面,并发信给管理员的程序
Oct 09 PHP
用php实现的获取网页中的图片并保存到本地的代码
Jan 05 PHP
写php分页时出现的Fatal error的解决方法
Apr 18 PHP
PHP代码网站如何防范SQL注入漏洞攻击建议分享
Mar 01 PHP
PHP中根据IP地址判断城市实现城市切换或跳转代码
Sep 04 PHP
基于AppServ,XAMPP,WAMP配置php.ini去掉警告信息(NOTICE)的方法详解
May 07 PHP
PHP改进计算字符串相似度的函数similar_text()、levenshtein()
Oct 27 PHP
php的crc32函数使用时需要注意的问题(不然就是坑)
Apr 21 PHP
PHP生成json和xml类型接口数据格式
May 17 PHP
php使用preg_match()函数验证ip地址的方法
Jan 07 PHP
PHP实现找出链表中环的入口节点
Jan 16 PHP
php设计模式之策略模式应用案例详解
Jun 17 PHP
学习php设计模式 php实现合成模式(composite)
Dec 08 #PHP
如何使用GDB调试PHP程序
Dec 08 #PHP
PHP MPDF中文乱码的解决方式
Dec 08 #PHP
PHP使用MPDF类生成PDF的方法
Dec 08 #PHP
学习php设计模式 php实现享元模式(flyweight)
Dec 07 #PHP
学习php设计模式 php实现策略模式(strategy)
Dec 07 #PHP
学习php设计模式 php实现状态模式
Dec 07 #PHP
You might like
一个简单计数器的源代码
2006/10/09 PHP
php中3种方法统计字符串中每种字符的个数并排序
2012/08/27 PHP
关于初学PHP时的知识积累总结
2013/06/07 PHP
thinkphp中U方法按路由规则生成url的方法
2018/03/12 PHP
javascript 获取网页标题代码实例
2014/01/22 Javascript
jQuery学习笔记之jQuery.extend(),jQuery.fn.extend()分析
2014/06/09 Javascript
Html5的placeholder属性(IE兼容)实现代码
2014/08/30 Javascript
bootstrap Validator 模态框、jsp、表单验证 Ajax提交功能
2017/02/17 Javascript
在使用JSON格式处理数据时应该注意的问题小结
2017/05/20 Javascript
AngularJS表单验证功能分析
2017/05/26 Javascript
jQuery实现的页面详情展开收起功能示例
2018/06/11 jQuery
用Electron写个带界面的nodejs爬虫的实现方法
2019/01/29 NodeJs
对node通过fs模块判断文件是否是文件夹的实例讲解
2019/06/10 Javascript
JS中的算法与数据结构之常见排序(Sort)算法详解
2019/08/16 Javascript
详解Vue 项目中的几个实用组件(ts)
2019/10/29 Javascript
解决Vue 刷新页面导航显示高亮位置不对问题
2019/12/25 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
解决vue单页面多个组件嵌套监听浏览器窗口变化问题
2020/07/30 Javascript
[48:46]完美世界DOTA2联赛PWL S2 SZ vs FTD.C 第二场 11.19
2020/11/19 DOTA
[53:10]完美世界DOTA2联赛决赛日 FTD vs GXR 第二场 11.08
2020/11/11 DOTA
Python 自动刷博客浏览量实例代码
2017/06/14 Python
Python 实现两个列表里元素对应相乘的方法
2018/11/14 Python
对python For 循环的三种遍历方式解析
2019/02/01 Python
对python 树状嵌套结构的实现思路详解
2019/08/09 Python
python numpy中cumsum的用法详解
2019/10/17 Python
Python装饰器实现方法及应用场景详解
2020/03/26 Python
删除pycharm鼠标右键快捷键打开项目的操作
2021/01/16 Python
基于 HTML5 WebGL 实现的垃圾分类系统
2019/10/08 HTML / CSS
HTML5实现经典坦克大战坦克乱走还能发出一个子弹
2013/09/02 HTML / CSS
澳大利亚排名第一的露营和户外设备在线零售商:Outbax
2020/05/06 全球购物
用JAVA实现一种排序,JAVA类实现序列化的方法(二种)
2014/04/23 面试题
日语专业个人的求职信
2013/12/03 职场文书
学校消防演习方案
2014/02/19 职场文书
2015年老干部工作总结
2015/04/23 职场文书
2016庆祝教师节新闻稿
2015/11/25 职场文书
2019年最新证婚词精选集!
2019/06/28 职场文书