学习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 04 PHP
php学习之数据类型之间的转换代码
May 29 PHP
php错误级别的设置方法
Jun 17 PHP
PHP批量检测并去除文件BOM头代码实例
May 08 PHP
简单谈谈php中ob_flush和flush的区别
Nov 27 PHP
主流PHP框架的优缺点对比分析
Dec 25 PHP
php实现httpRequest的方法
Mar 13 PHP
PHP二维数组去重实例分析
Nov 18 PHP
zend框架实现支持sql server的操作方法
Dec 08 PHP
Laravel相关的一些故障解决
Aug 19 PHP
PhpSpreadsheet设置单元格常用操作汇总
Nov 13 PHP
Nginx+php配置文件及原理解析
Dec 09 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
WINDOWS服务器安装多套PHP的另类解决方案
2006/10/09 PHP
10个可以简化php开发过程的MySQL工具
2010/04/11 PHP
PHP生成唯一的促销/优惠/折扣码(附源码)
2012/12/28 PHP
smarty内部日期函数html_select_date()用法实例分析
2015/07/08 PHP
Linux系统下PHP-FPM的安装和配置教程
2015/08/17 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
2019/05/08 PHP
utf8的编码算法 转载
2006/12/27 Javascript
JavaScript 未结束的字符串常量常见解决方法
2010/01/24 Javascript
用Javascript评估用户输入密码的强度(Knockout版)
2011/11/30 Javascript
jquery 滚动条事件简单实例
2013/07/12 Javascript
BootStrap实现手机端轮播图左右滑动事件
2016/10/13 Javascript
jquery实现放大镜简洁代码(推荐)
2017/06/08 jQuery
详解webpack + react + react-router 如何实现懒加载
2017/11/20 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
2018/03/08 Javascript
微信小程序使用wxParse解析html的方法教程
2018/07/06 Javascript
vue前端和Django后端如何查询一定时间段内的数据
2021/02/28 Vue.js
wxPython定时器wx.Timer简单应用实例
2015/06/03 Python
Python打印斐波拉契数列实例
2015/07/07 Python
图文详解WinPE下安装Python
2016/05/17 Python
Python中强大的命令行库click入门教程
2016/12/26 Python
Python实现按特定格式对文件进行读写的方法示例
2017/11/30 Python
Pycharm在创建py文件时,自动添加文件头注释的实例
2018/05/07 Python
Python numpy实现二维数组和一维数组拼接的方法
2018/06/05 Python
解决Python pip 自动更新升级失败的问题
2020/02/21 Python
Python代码执行时间测量模块timeit用法解析
2020/07/01 Python
Python 在局部变量域中执行代码
2020/08/07 Python
python爬虫智能翻页批量下载文件的实例详解
2021/02/02 Python
与世界上最好的跑步专业品牌合作:Fleet Feet
2019/03/22 全球购物
应届大学毕业生找工作的求职信范文
2013/11/29 职场文书
《跨越海峡的生命桥》教学反思
2014/02/24 职场文书
县政府办公室领导班子对照检查材料思想汇报
2014/09/28 职场文书
破坏寝室公物检讨书
2014/11/17 职场文书
2015年教师节活动总结
2015/03/20 职场文书
2016年教师反腐倡廉心得体会
2016/01/13 职场文书
使用HBuilder制作一个简单的HTML5网页
2022/07/07 HTML / CSS
el-form每行显示两列底部按钮居中效果的实现
2022/08/05 HTML / CSS