PHP设计模式之命令模式的深入解析


Posted in PHP onJune 13, 2013

命令模式(Command),命令模式是封装一个通用操作的机制。

如果你熟悉C或PHP,你可能已经遇到过Command,它相当于程序中的:回调(callback)。回调通常使用一个函数指针或数据结构如PHP中的字符串和数组实现,Command是在一个方法调用之上的抽象,它吸收了所有面向对象的好处:合成、继承和处理。

例如,《设计模式》一书推荐使用Command存储用户行为链,以支持撤销和重做操作。

注意PHP 5.3函数编程能力(闭包)可以被当做Command模式的一个本地实现,但为每一个命令层次结构使用抽象数据类型有助于类型安全。

PHP设计模式之命令模式的深入解析

在这个模式中,Invoker(调用者)知道传递给它的Command,无需依赖于真实的ConcreteCommand(具体的命令)实现,解决了通过配置进行方法调用相关的问题,如UI控件按钮和菜单等引用一个Command,它们的行为是通过通用的ConcreteCommand实例呈现的。
参与者:
◆Command(命令):在一个方法调用之上定义一个抽象;
◆ConcreteCommand(具体的命令):一个操作的实现;
◆Invoker(调用者):引用Command实例作为它可用的操作。
下面的代码展示了Validator组件作为Command对象实现的示例:

/**  
 * The Command abstraction.  
 * In this case the implementation must return a result,  
 * sometimes it only has side effects.  
 */ 
interface Validator  
{  
    /**  
     * The method could have any parameters.  
     * @param mixed  
     * @return boolean  
     */ 
    public function isValid($value);  
}  /**  
 * ConcreteCommand.  
 */ 
class MoreThanZeroValidator implements Validator  
{  
    public function isValid($value)  
    {  
        return $value > 0;  
    }  
}  
/**  
 * ConcreteCommand.  
 */ 
class EvenValidator implements Validator  
{  
    public function isValid($value)  
    {  
        return $value % 2 == 0;  
    }  
}  
/**  
 * The Invoker. An implementation could store more than one  
 * Validator if needed.  
 */ 
class ArrayProcessor  
{  
    protected $_rule;  
    public function __construct (Validator $rule)  
    {  
        $this->_rule = $rule;  
    }  
    public function process(array $numbers)  
    {  
        foreach ($numbers as $n) {  
            if ($this->_rule->IsValid($n)) {  
                echo $n, "\n";  
            }  
        }  
    }  
}  
// Client code  
$processor = new ArrayProcessor(new EvenValidator());  
$processor->process(array(1, 20, 18, 5, 0, 31, 42));

使用PHP设计模式中的命令模式的一些注意事项:
◆方法调用中的某些参数可以在构造ConcreteCommand时提供,有效地局部套用(currying)原始函数;
◆一个Command可以被看作是一个非常简单的只有一个方法的策略(Strategy),重点放在对象的操作上;
◆ConcreteCommands也要组织它们需要的每一个资源,以实现它们的目标,主要是行为的Receiver(接受者),它们调用方法执行一个Command;
◆复合模式,装饰模式和其它模式都可以和命令模式组合,获得更多的Command,装饰Command等等。
PHP 相关文章推荐
一些PHP写的小东西
Dec 06 PHP
再次研究下cache_lite
Feb 14 PHP
PHP批量生成静态HTML的简单原理和方法
Apr 20 PHP
ThinkPHP安装和设置
Jul 27 PHP
PHP实现多维数组转字符串和多维数组转一维数组的方法
Aug 08 PHP
Zend Framework教程之MVC框架的Controller用法分析
Mar 07 PHP
PHP获取用户访问IP地址的5种方法
May 16 PHP
golang与php实现计算两个经纬度之间距离的方法
Jul 22 PHP
php注册和登录界面的实现案例(推荐)
Oct 24 PHP
php curl获取到json对象并转成数组array的方法
May 31 PHP
php基于Redis消息队列实现的消息推送的方法
Nov 28 PHP
如何在PHP中生成随机数
Jun 04 PHP
深入Memcache的Session数据的多服务器共享详解
Jun 13 #PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
Jun 13 #PHP
判断php数组是否为索引数组的实现方法
Jun 13 #PHP
深入解析yii权限分级式访问控制的实现(非RBAC法)
Jun 13 #PHP
PHP 基于Yii框架中使用smarty模板的方法详解
Jun 13 #PHP
关于PHP二进制流 逐bit的低位在前算法(详解)
Jun 13 #PHP
php读取二进制流(C语言结构体struct数据文件)的深入解析
Jun 13 #PHP
You might like
一步一步学习PHP(5) 类和对象
2010/02/16 PHP
PHP图像识别技术原理与实现
2016/10/27 PHP
thinkphp的dump函数无输出实例代码
2016/11/15 PHP
php检测mysql表是否存在的方法小结
2017/07/20 PHP
用javascript动态调整iframe高度的代码
2007/04/10 Javascript
js对象的比较
2011/02/26 Javascript
分享14个很酷的jQuery导航菜单插件
2011/04/25 Javascript
IE8提示Invalid procedure call or argument 异常的解决方法
2012/09/30 Javascript
jQuery页面图片伴随滚动条逐渐显示的小例子
2013/03/21 Javascript
Javascript封装DOMContentLoaded事件实例
2014/06/12 Javascript
jQuery表格插件datatables用法总结
2014/09/05 Javascript
js用拖动滑块来控制图片大小的方法
2015/02/27 Javascript
JavaScript实现的浮动层框架用法实例分析
2015/10/10 Javascript
jQuery获取select选中的option的value值实现方法
2016/08/29 Javascript
浅谈Angular2 ng-content 指令在组件中嵌入内容
2017/08/18 Javascript
javascript回调函数详解
2018/02/06 Javascript
详解Vue Elememt-UI构建管理后台
2018/02/27 Javascript
javaScript中"=="和"==="的区别详解
2018/03/16 Javascript
iview同时验证多个表单问题总结
2018/09/29 Javascript
一篇文章介绍redux、react-redux、redux-saga总结
2019/05/23 Javascript
Vue 实现输入框新增搜索历史记录功能
2019/10/15 Javascript
python检测服务器是否正常
2014/02/16 Python
python中实现定制类的特殊方法总结
2014/09/28 Python
处理Python中的URLError异常的方法
2015/04/30 Python
Python使用正则表达式实现文本替换的方法
2017/04/18 Python
快速入门python学习笔记
2017/12/06 Python
Python生成指定数量的优惠码实操内容
2019/06/18 Python
Django使用Celery加redis执行异步任务的实例内容
2020/02/20 Python
python_matplotlib改变横坐标和纵坐标上的刻度(ticks)方式
2020/05/16 Python
python判断字符串以什么结尾的实例方法
2020/09/18 Python
Python实现曲线拟合的最小二乘法
2021/02/19 Python
秋季运动会加油稿200字
2014/01/11 职场文书
幼儿园教研活动总结
2014/04/30 职场文书
党的群众路线个人对照检查材料
2014/09/23 职场文书
2014年办公室文员工作总结
2014/11/12 职场文书
原告离婚代理词
2015/05/23 职场文书