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 相关文章推荐
对javascript和select部件的结合运用
Oct 09 PHP
PHP 将图片按创建时间进行分类存储的实现代码
Jan 05 PHP
php数组函数序列之krsort()- 对数组的元素键名进行降序排序,保持索引关系
Nov 02 PHP
php中++i 与 i++ 的区别
Aug 08 PHP
使用迭代器 遍历文件信息的详解
Jun 08 PHP
PHP图片等比例缩放生成缩略图函数分享
Jun 10 PHP
php中magic_quotes_gpc对unserialize的影响分析
Dec 16 PHP
php实现多城市切换特效
Aug 09 PHP
如何解决phpmyadmin导入数据库文件最大限制2048KB
Oct 09 PHP
PHP性能优化大全(php.ini)
May 20 PHP
PHP+Ajax无刷新带进度条图片上传示例
Feb 08 PHP
PHP编程实现阳历转换为阴历的方法实例
Aug 08 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实现MySQL数据库备份与还原类实例
2014/12/09 PHP
PHP创建word文档的方法(平台无关)
2016/03/29 PHP
PHP如何获取Cookie并实现模拟登录
2020/07/16 PHP
defer属性导致引用JQuery的页面报“浏览器无法打开网站xxx,操作被中止”错误的解决方法
2010/04/27 Javascript
EasySlider 基于jQuery功能强大简单易用的滑动门插件
2010/06/11 Javascript
JavaScript类和继承 prototype属性
2010/09/03 Javascript
JS俄罗斯方块,包含完整的设计理念
2010/12/11 Javascript
Script标签与访问HTML页面详解
2014/01/10 Javascript
js实现jquery的offset()方法实例
2015/01/10 Javascript
JavaScript中constructor()方法的使用简介
2015/06/05 Javascript
Jquery日历插件制作简单日历
2015/10/28 Javascript
基于JavaScript将表单序列化类型的数据转化成对象的处理(允许对象中包含对象)
2015/12/28 Javascript
利用canvas实现的加载动画效果实例代码
2017/07/05 Javascript
JS获取字符对应的ASCII码实例
2017/09/10 Javascript
你应该知道的几类npm依赖包管理详解
2017/10/06 Javascript
vue使用axios跨域请求数据问题详解
2017/10/18 Javascript
JS实现获取汉字首字母拼音、全拼音及混拼音的方法
2017/11/14 Javascript
基于Vue的延迟加载插件vue-view-lazy
2018/05/21 Javascript
javascript实现滚轮轮播图片
2020/12/13 Javascript
Python中的类学习笔记
2014/09/23 Python
Python实现以时间换空间的缓存替换算法
2016/02/19 Python
Python实现的根据文件名查找数据文件功能示例
2018/05/02 Python
python实现图片筛选程序
2018/10/24 Python
python求最大值,不使用内置函数的实现方法
2019/07/09 Python
Python使用GitPython操作Git版本库的方法
2020/02/29 Python
Python实现异步IO的示例
2020/11/05 Python
Jowissa官方网站:瑞士制造的手表,优雅简约的设计
2020/07/29 全球购物
linux面试题参考答案(1)
2016/01/22 面试题
程序员岗位职责
2013/11/11 职场文书
医药销售自荐书
2014/05/29 职场文书
优秀三好学生事迹材料
2014/08/31 职场文书
2014年学校食堂工作总结
2014/11/25 职场文书
婚礼父母致辞
2015/07/28 职场文书
《梅花魂》教学反思
2016/02/18 职场文书
分析SQL窗口函数之排名窗口函数
2022/04/21 Oracle
MySql统计函数COUNT的具体使用详解
2022/08/14 MySQL