学习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 相关文章推荐
刚才在简化php的库,结果发现很多东西
Dec 31 PHP
PHP批量删除、清除UTF-8文件BOM头的代码实例
Apr 14 PHP
php对包含html标签的字符串进行截取的函数分享
Jun 19 PHP
PHP中的替代语法介绍
Jan 09 PHP
在Nginx上部署ThinkPHP项目教程
Feb 02 PHP
php实现随机显示图片方法汇总
May 21 PHP
WordPress主题制作之模板文件的引入方法
Dec 28 PHP
深入浅析php中sprintf与printf函数的用法及区别
Jan 08 PHP
PHP GD库相关图像生成和处理函数小结
Sep 30 PHP
PHP超低内存遍历目录文件和读取超大文件的方法
May 01 PHP
laravel 框架结合关联查询 when()用法分析
Nov 22 PHP
PHP延迟静态绑定使用方法实例解析
Sep 05 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
ajax+php打造进度条代码[readyState各状态说明]
2010/04/12 PHP
php下连接ftp实现文件的上传、下载、删除文件实例代码
2010/06/03 PHP
用php的ob_start来生成静态页面的方法分析
2011/03/09 PHP
支持中文的php加密解密类代码
2011/11/27 PHP
浅析php变量作用域的一些问题
2013/08/08 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
给moz-firefox下添加IE方法和属性
2007/04/10 Javascript
js 关键词高亮(根据ID/tag高亮关键字)案例介绍
2013/01/21 Javascript
使用js修改客户端注册表的方法
2013/08/09 Javascript
js+jquery实现图片裁剪功能
2015/01/02 Javascript
js 判断附件后缀的简单实现方法
2016/10/11 Javascript
实现一个简单的vue无限加载指令方法
2017/01/10 Javascript
Angularjs自定义指令实现三级联动 选择地理位置
2017/02/13 Javascript
ajax实现加载页面、删除、查看详细信息 bootstrap美化页面!
2017/03/14 Javascript
Mongoose实现虚拟字段查询的方法详解
2017/08/15 Javascript
实例教学如何写vue插件
2017/11/30 Javascript
element-ui中的select下拉列表设置默认值方法
2018/08/24 Javascript
解决layer弹出层的内容页点击按钮跳转到新的页面问题
2019/09/14 Javascript
解决vue页面刷新,数据丢失的问题
2020/11/24 Vue.js
vuex Module将 store 分割成模块的操作
2020/12/07 Vue.js
[04:32]DOTA2著名解说配音敌法师 现场专访海涛怒切假腿
2013/12/20 DOTA
python使用递归解决全排列数字示例
2014/02/11 Python
Python计算两个日期相差天数的方法示例
2017/05/23 Python
python将unicode转为str的方法
2017/06/21 Python
python日期时间转为字符串或者格式化输出的实例
2018/05/29 Python
零基础使用Python读写处理Excel表格的方法
2019/05/02 Python
django 做 migrate 时 表已存在的处理方法
2019/08/31 Python
Pandas替换及部分替换(replace)实现流程详解
2020/10/12 Python
Window10上Tensorflow的安装(CPU和GPU版本)
2020/12/15 Python
html5的新增的标签和废除的标签简要概述
2013/02/20 HTML / CSS
外贸业务员求职自荐信分享
2013/09/21 职场文书
学校安全责任书
2014/04/14 职场文书
小学生国庆演讲稿
2014/09/05 职场文书
Css预编语言及区别详解
2021/04/25 HTML / CSS
oracle连接ODBC sqlserver数据源的详细步骤
2021/07/25 Oracle
python使用torch随机初始化参数
2022/03/22 Python