php单件模式结合命令链模式使用说明


Posted in PHP onSeptember 07, 2008

可能对于部分人来说,文章内容过于浅显,这是送给初学者的教程,因为时间比较紧(要陪老婆逛街,呵呵),其中出现了设计不规范的,代码书写不规范的,bug等等还望各路大侠指出来,方便大家共同进步.本人水平有限.^_^

相信大家都已经读过很多关于在php中应用设计模式的书籍或是文章,但是很少有直接给予实例,大部分看完之后有种迷迷糊糊的感觉,如果没有项目实践,很难将设计模式部分弄清楚.

为避免代码过于复杂.没有添加异常处理等内容.
单件模式以及命令链模式的基础知识,大家自己google一下.不详细讲了.下面直接看实例:

<?php 
/* 
*@author:NoAngels 
*@time:08年08月30日 
*/ 
interface IRunAction{ 
//获取类中定义的可以被APP中run的方法 
static function LoadActions(); 
//类中的入口函数调用该类中其他函数用 
function runAction($action, $args); 
} 
/* 
*APP类系统的核心部分 
*/ 
class APP{ 
static private $__instance = null; 
static private $__commands = array(); 
static private $__flag = 1; 
private function __construct(){} 
//单件模式设计获取该类的唯一实例 
static function Load(){ 
if(self::$__instance == null) self::$__instance = new APP; 
return self::$__instance; 
} 
//添加命名到APP的$__instance中每次添加新命令的时候检查是否之前已经添加过一个该类的实例 
//如果有就忽略操作如果没有就添加进来 
public function addCommand($cmdName){ 
foreach(self::$__commands as $cmd){ 
if(strtolower(get_class($cmd)) == strtolower(get_class($cmdName))){ 
self::$__flag = 0; 
break; 
} 
} 
if(self::$__flag == 1) self::$__commands[] = $cmdName; 
self::$__flag = 1; 
} 
//命令链模式设计的核心部分调用实例的入口函数 
//首先检查是否在类中允许调用该操作如果没有就提示未定义操作退出 
public function runCommand($action, $args){ 
self::$__flag = 0; 
foreach(self::$__commands as $cmd){ 
if(in_array($action, $cmd->LoadActions())){ 
self::$__flag = 1; 
$cmd->runAction($action, $args); 
} 
} 
if(self::$__flag == 0){ 
self::$__flag = 1; 
exit("undefined action by action : $action"); 
} 
} 
//删除某个类的实例,只要指定类的名字即可 
public function removeCommand($className){ 
foreach(self::$__commands as $key=>$cmd){ 
if(strtolower(get_class($cmd)) == strtolower($className)){ 
unset(self::$__commands[$key]); 
} 
} 
} 
//供大家测试用看看是否添加以及删除成功 
public function viewCommands(){ 
echo(count(self::$__commands)); 
} 
} 
//类User实现接口IRunAction 
class User implements IRunAction{ 
//定义可以调用的操作 
static private $__actions = array('addUser', 'modifyUser', 'removeUser'); 
//获取可以调用的操作,实际过程中不要直接就爱你个$__actions设计成public调用 
//而应该设计一个LoadActions函数获取$__actions的值 
static public function LoadActions(){ 
return self::$__actions; 
} 
//运行指定函数 
public function runAction($action, $args){ 
//不明白这个函数使用的可以参看手册 
call_user_func(array($this,$action), $args); 
} 
//测试函数而已 
protected function addUser($name){ 
echo($name); 
} 
} 
//类Test同类User 
class Test implements IRunAction{ 
static private $__actions = array('addTest', 'modifyTest', 'removeTest'); 
static public function LoadActions(){ 
return self::$__actions; 
} 
public function runAction($action, $args){ 
call_user_func(array($this,$action), $args); 
} 
protected function addTest($name){ 
echo($name); 
} 
} 
//以下是测试代码 
APP::Load()->addCommand(new User); 
APP::Load()->addCommand(new User); 
APP::Load()->addCommand(new User); 
APP::Load()->addCommand(new User); 
APP::Load()->runCommand('addUser', 'NoAngels'); 
APP::Load()->addCommand(new Test); 
APP::Load()->runCommand('addTest', null);

APP类用单件模式设计,它是系统的核心部分.相信大家看代码就知道了Load方法是载入APP类实例,相当于有些书籍中的getInstance静态方法.他有addCommand,runCommand,removeCommand三个public方法.runCommand是核心部分.同时也是命令链模式的核心启动程序.具体实现请看源代码.代码写的已经很清楚了,就此不再赘述.
类User,Test实现了接口IRunAction,这两个类中都定义了一个静态私有变量$__actions,为一数组,其中包含了可以被APP的runCommand函数调用的操作.

下面是系统的运行流程:

APP启动
-------addCommand,将将要运行的操作所属的类添加到APP中.如果添加的类是用单件模式设计的.可以如下添加addCommand(SingletonClass::Load()).否则可以如下调

addCommand(new someClass)
-------runCommand.运行操作.比如在User类中有一操作addUser.我直接可以启用runCommand($acttion, $args).在APP中循环遍历$__commands数组,如果其中某个类的实例拥有该操作,就调用该实例的runAction函数.如果你没有将某个类的实例利用addCommand添加进来,就提示未定义操作,退出.
在类User和类Test中的runAction调用了call_user_func这个非常使用的函数.调用该类中对应函数.

提示:讲解与实例部分就到此了,具体你怎么理解,以及如何将该思想利用,就看你自己的理解,凡事必须自己动手才行.(ps:可以做成框架中的单一入口文件,实不实现MVC就看你自己是怎么想的了.)

实际运行效果如下:
php单件模式结合命令链模式使用说明
限于语文水平,有什么不理解的可以联系我.
以后有时间了再给大家写点文章.

PHP 相关文章推荐
JS 网站性能优化笔记
May 24 PHP
php小技巧 把数组的键和值交换形成了新的数组,查找值取得键
Jun 02 PHP
批量获取memcache值并按key的顺序返回的实现代码
Jun 14 PHP
PHP中error_reporting()函数的用法(修改PHP屏蔽错误)
Jul 01 PHP
腾讯微博提示missing parameter errorcode 102 错误的解决方法
Dec 22 PHP
php连接oracle数据库及查询数据的方法
Dec 29 PHP
PHP中PDO的事务处理分析
Apr 07 PHP
微信支付PHP SDK ―― 公众号支付代码详解
Sep 13 PHP
php中array_slice和array_splice函数解析
Oct 18 PHP
Yii框架使用魔术方法实现跨文件调用功能示例
May 20 PHP
php curl上传、下载、https登陆实现代码
Jul 23 PHP
PHP工厂模式、单例模式与注册树模式实例详解
Jun 03 PHP
网友原创的PHP模板类代码
Sep 07 #PHP
php 特殊字符处理函数
Sep 05 #PHP
php include,include_once,require,require_once
Sep 05 #PHP
php生成随机数或者字符串的代码
Sep 05 #PHP
PHP通用分页类page.php[仿google分页]
Aug 31 #PHP
php将数据库中的电话号码读取出来并生成图片
Aug 31 #PHP
PHP生成HTML静态页面实例代码
Aug 31 #PHP
You might like
php 静态变量的初始化
2009/11/15 PHP
$()JS小技巧
2007/07/21 Javascript
js 判断checkbox是否选中的实现代码
2010/11/23 Javascript
JS.findElementById()使用介绍
2013/09/21 Javascript
js读写json文件实例代码
2014/10/21 Javascript
详解JavaScript数组和字符串中去除重复值的方法
2016/03/07 Javascript
EditPlus 正则表达式 实战(3)
2016/12/15 Javascript
jquery与ajax获取特殊字符实例详解
2017/01/08 Javascript
使用Xcache缓存器加速PHP网站的配置方法
2017/04/22 Javascript
Angular通过指令动态添加组件问题
2018/07/09 Javascript
详解在vue-cli中使用graphql即vue-apollo的用法
2018/09/08 Javascript
详解react native页面间传递数据的几种方式
2018/11/07 Javascript
基于vue中的scoped坑点解说
2020/09/04 Javascript
vue-cli3自动消除console.log()的调试信息方式
2020/10/21 Javascript
[28:28]Ti4 冒泡赛第二天NEWBEE vs NaVi 2
2014/07/15 DOTA
[01:09]2014DOTA2国际邀请赛 TI4西雅图DOTA2 中国美女coser加油助威
2014/07/20 DOTA
[01:50:49]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第三场 1月24日
2021/03/11 DOTA
在Python的web框架中中编写日志列表的教程
2015/04/30 Python
Python检测QQ在线状态的方法
2015/05/09 Python
WIn10+Anaconda环境下安装PyTorch(避坑指南)
2019/01/30 Python
Python3中函数参数传递方式实例详解
2019/05/05 Python
python实现美团订单推送到测试环境,提供便利操作示例
2019/08/09 Python
python+selenium+Chrome options参数的使用
2020/03/18 Python
Python如何实现FTP功能
2020/05/28 Python
Python使用Pygame绘制时钟
2020/11/29 Python
Python 生成短8位唯一id实战教程
2021/01/13 Python
Kate Spade美国官网:纽约新兴时尚品牌,以包包闻名于世
2017/11/09 全球购物
见习期自我鉴定
2013/11/07 职场文书
酒吧员工的岗位职责
2013/11/26 职场文书
服装设计师职业生涯规划范文
2014/02/28 职场文书
爱国主义教育演讲稿
2014/08/26 职场文书
2014年大学生工作总结
2014/11/20 职场文书
三好学生评语大全
2014/12/29 职场文书
证劵公司反洗钱宣传活动总结
2015/05/08 职场文书
5行Python代码实现一键批量扣图
2021/06/29 Python
springboot 全局异常处理和统一响应对象的处理方式
2022/06/28 Java/Android