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

 更新时间:2008年09月07日 12:05:21   作者:  
初学者对于设计模式肯定存在着很多不明白之处,今天刚好周末,就抽出来点时间写了一个单件模式结合命令链模式打造系统核心的文章
可能对于部分人来说,文章内容过于浅显,这是送给初学者的教程,因为时间比较紧(要陪老婆逛街,呵呵),其中出现了设计不规范的,代码书写不规范的,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学习的路线图

    一直都想走上码农的道路,奈何当年没有学好。一直与码农无缘。现在又想做一些码农就下了一套某个培训机构的php视频来看。希望能走上码农的道路
    2013-07-07
  • 如何用PHP实现多线程编程

    如何用PHP实现多线程编程

    原以为 PHP 普遍都是单线程模型,并不适合多线程领域,发现PHP的多线程也颇有可取之处,用来解决某些问题竟然非常适合。本文对比多进程介绍了下多线程的优势和适用场景,提出了一种巧用方案,并使用PHP代码实现了多线程的常见用法。
    2021-05-05
  • PHP 错误之引号中使用变量

    PHP 错误之引号中使用变量

    当看到错误提示 syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING
    2009-05-05
  • PHP实现二维数组按某列进行排序的方法

    PHP实现二维数组按某列进行排序的方法

    这篇文章主要介绍了PHP实现二维数组按某列进行排序的方法,结合实例形式分析了php二维数组排序的技巧,涉及array_multisort函数的使用方法,需要的朋友可以参考下
    2016-11-11
  • PHP使用互斥锁确保代码的线程安全的操作示例

    PHP使用互斥锁确保代码的线程安全的操作示例

    在多线程和高并发的环境下,我们经常会遇到需要确保代码段互斥执行的场景,比如,在电商平台中,当多个用户同时购买同一件商品时,如何确保库存的扣减是线程安全的,今天,我们将一起探讨这个问题,并介绍一个名为 wise-locksmith 的 PHP 互斥锁库
    2024-11-11
  • php中目录,文件操作详谈

    php中目录,文件操作详谈

    php中目录,文件操作详谈...
    2007-03-03
  • PHP实现路由映射到指定控制器

    PHP实现路由映射到指定控制器

    这篇文章主要为大家详细介绍了PHP实现路由映射到指定控制器的相关资料,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • php单元测试phpunit入门实例教程

    php单元测试phpunit入门实例教程

    这篇文章主要介绍了php单元测试phpunit,结合实例形式分析了php单元测试phpunit的基本概念、使用方法及相关注意事项,需要的朋友可以参考下
    2017-11-11
  • php json转换成数组形式代码分享

    php json转换成数组形式代码分享

    这篇文章主要介绍了php json转换成数组形式代码分享,需要的朋友可以参考下
    2014-11-11
  • PHP设计模式之调解者模式的深入解析

    PHP设计模式之调解者模式的深入解析

    本篇文章是对PHP设计模式中的调解者模式进行了详细的分析介绍,需要的朋友参考下
    2013-06-06

最新评论