学习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 相关文章推荐
fgetcvs在linux的问题
Jan 15 PHP
ThinkPHP CURD方法之limit方法详解
Jun 18 PHP
PHP生成数组再传给js的方法
Aug 07 PHP
php筛选不存在的图片资源
Apr 28 PHP
PHP使用ODBC连接数据库的方法
Jul 18 PHP
PHP发送短信代码分享
Aug 11 PHP
php+jQuery+Ajax实现点赞效果的方法(附源码下载)
Jul 21 PHP
round robin权重轮循算法php实现代码
May 28 PHP
PHP获取input输入框中的值去数据库比较显示出来
Nov 16 PHP
PHP解压ZIP文件到指定文件夹的方法
Nov 17 PHP
php+mysql实现简单登录注册修改密码网页
Nov 30 PHP
PHP下载远程图片的几种方法总结
Apr 07 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
PHP-MySQL教程归纳总结
2008/06/07 PHP
如何获知PHP程序占用多少内存(memory_get_usage)
2012/09/23 PHP
PHP遍历目录并返回统计目录大小
2014/06/09 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
PHP中数据类型转换的三种方式
2015/04/02 PHP
浅谈php7的重大新特性
2015/10/23 PHP
ThinkPHP中order()使用方法详解
2016/04/19 PHP
Yii实现显示静态页的方法
2016/04/25 PHP
window.open()弹出居中的窗口
2007/02/01 Javascript
基于MooTools的很有创意的滚动条时钟动画
2010/11/14 Javascript
jQuery点击后一组图片左右滑动的实现代码
2012/08/16 Javascript
jquery中$each()方法的使用指南
2015/04/30 Javascript
javascript倒计时效果实现
2015/11/12 Javascript
js只执行1次的函数示例
2016/07/20 Javascript
详解网站中图片日常使用以及优化手法
2017/01/09 Javascript
JS常见简单正则表达式验证功能小结【手机,地址,企业税号,金额,身份证等】
2017/01/22 Javascript
D3.js实现拓扑图的示例代码
2018/06/30 Javascript
详解webpack打包后如何调试的方法步骤
2018/11/07 Javascript
layui 实现加载动画以及非真实加载进度的方法
2019/09/23 Javascript
[00:16]热血竞技场
2019/03/06 DOTA
python中关于时间和日期函数的常用计算总结(time和datatime)
2013/03/08 Python
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
python使用mitmproxy抓取浏览器请求的方法
2019/07/02 Python
解决python 文本过滤和清理问题
2019/08/28 Python
Django异步任务线程池实现原理
2019/12/17 Python
Python 去除字符串中指定字符串
2020/03/05 Python
jupyter 添加不同内核的操作
2021/02/06 Python
瑞士设计师家具和家居饰品网上商店:Bruno Wickart
2019/03/18 全球购物
工程师求职简历的自我评价分享
2013/10/10 职场文书
应届大学生的推荐信
2013/11/20 职场文书
英文自荐信格式
2013/11/28 职场文书
酒店中秋节促销方案
2014/01/30 职场文书
爱之链教学反思
2014/04/30 职场文书
2014年内勤工作总结
2014/11/24 职场文书
捐款仪式主持词
2015/07/04 职场文书
MySQL触发器的使用
2021/05/24 MySQL