文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>小议大型开发中php的设计模式之单件模式

小议大型开发中php的设计模式之单件模式

时间:2011-04-15  来源:李惟

以往在php环境下谈到的设计模式往往都是理论一大堆,加之php较少在实现大型应用方面,所以很多时候设计模式成了一种摆设,本文从较简单的设计模型中的单件模式说起,谈谈应用,阐述设计模型对于复杂环境中的大内涵.



从一个简单的例子着手,在一些应用中,我们希望有些对象是全局作用的,如下:

include('example.class.php');
$obj = new example();

class a1
{
function ex()
{
  global $obj;
  $obj->v = 1;  //注意这里,需要调用外部对象
}
}

class a2
{
function ex()
{
  global $obj;
  $obj->v ++;        //注意这里,再次调用外部对象
}
}

$a1 = new a1;
$a1->ex();
$a2 = new a2;
$a2->ex();

从上面简单的例子看到,$obj对象被其它多个对象所使用,这时通常需要的几个步骤:
1. include类文件
2. 实例化
3. 在使用时global声明全局性

倘若有种情况需要在不同的对象中调用多个外部对象,那么情况有可能就是如下:

include('example.class.php');
$obj = new example();
include('example2.class.php');
$obj2 = new example2();
...
$obj3
$obj4
$obj_n
...
class a1
{
function ex()
{
  global $obj;
  $obj->v = 1;
  global $obj2;
  $obj2->v = 1;
  ...
  global $obj_n;
  $obj_n->v = 1;
}
}
class a2
{
...

局面开始不好收拾了,于是我们使用一种方法封装这个过程,首先定义一个类,这个类专门负责将另一个指定的类自动实例化成对象:

class Singleton
{
private $objs;
public function instance($obj)
{
   if($this->objs[$obj] == null)        //判断是否已经实例化
   {
    include($obj.'.class.php');
    $this->objs[$obj] = new $obj;
   }
   return $this->objs[$obj];
}
}
$Singleton = new Singleton();

那么之前的局面就演变成如下:

...
class a1
{
function ex()
{
  global $Singleton;                //只需一次global声明
  $Singleton->reg('example')->v = 1;
  $Singleton->reg('example2')->v = 1;
  ...
  $Singleton->reg('example_n')->v = 1;
  ...
}
}

class a2
{
...

那么其中通过$Singleton对象访问类就是经典的单件模式了,这边仅仅是说明了单件模式概念,以下说明使用单件模式的好处.


一.文件包含与对象实例化的透明化

我们发现上边在使用$Singleton仍然需要global声明,这时可以使用函数来"包装"

function instance($class_name)
{
static $instance;
if($instance == false)
  $instance = new Singleton();
return $instance->reg($class_name);        //调用Singleton对象,实例化类并返回对象
}

那么最终的调用就是这样的

...
class a1
{
function ex()
{
  //这里我们无需使用global,直接使用example类生成的对象
  instance('example')->v = 1;
  instance('example2')->v = 1;
  ...
}
}
class a2
{
...

这时我们看到使用一个外部对象就变得简单而清晰了,我们无需关注example类所在文件的包含和实例化就能直接使用,
这就是使用单件模式对对象透明化的作用.




二.全局(作用域)应用
通过之前的代码得知,我们可以在任何时候使用Singleton得到我们希望使用的对象:

class a1
{
function ex()
{
  instance('example')->v = 1;        //使用单件模式针对example类生成对象并进行操作
  ...
}
}
...
class a2
{
function ex()
{
  instance('example')->v ++;        //在不同作用域对同一个对象进行操作
  ...
}
}

在a1和a2的类中调用example实现的对象时,无需考虑作用域及global声明,实现跨全局对象的应用.
        

三.事务性/一致性的应用
在一些多线程的语言中,有时希望在同一时间只能有一个线程对对象进行操作,这是线程安全问题,而在php中,类似的情况是资源竞争的解决,如对共享数据的读写,而使用单件模式则很容易做到,在原有单件模式的基础上,增加了事务性

class Singleton_safe
{
private $objs;
private $mutex;        
public function reg($obj)
{
   if($objs[$obj] == null)        //判断是否已经实例化
   {
    include($obj.'.class.php');
    $this->mutex[$obj] = sem_get(fileinode($obj.'.class.php'),1,0666,true);
    sem_acquire($this->mutex[$obj]);        //这边使用信号量做同步
    $this->objs[$obj] = new $obj;
   }
   return $this->objs[$obj];
}

function __destruct()
{
   foreach($this->mutex as $sem_id)
   {
    sem_release($sem_id);        //单件模式下析构时删除所有对象的信号量锁
    //sem_remove($sem_id);        
   }
}
}

当然,和其它语言不一样,这个简单的例子实现的事务周期是对象在整个php进程的运行期间,这样保证了在调用Singleton_safe实现单例模式下,派生对象的所有操作是系统唯一的.


*四.其它扩展
有时在使用或调试对象时,需要记录对象的调用次数,可增加一些记数功能,

class Singleton
{
private $objs;
private $record = 0;
public function reg($obj)
{
   if($this->objs[$obj] == null)        //判断是否已经实例化
   {
    include($obj.'.class.php');
    $this->objs[$obj] = new $obj;
   }
   $this->record[$obj]++;                //累计对象的使用次数
   return $this->objs[$obj];
}

public get_record($obj_name)
{
  return $this->record[$obj_name];     //获取对象的使用次数
}
}
....
function instance($class_name == null)
{
static $instance;
if($instance == false)
  $instance = new Singleton();
if($class_name == null) return $instance;
return $instance->reg($class_name);
}

使用时

instance('example')->v = 1;
instance('example')->v++;
echo 'example被使用次数为:',instance()->get_record('example');//2

此外在一些其它语言上,如Cpp上也可结合对象的创建与销毁等内存管理工作.



单件模式是设计模式中较简单同时也是使用最为频繁的模式之一,仅仅这样一个简单的实现便可以帮我们做很多事,也让我们更多更有必要地去了解设计模式的价值所在.
附:C语言扩展编写的单件库
http://lajabs.net/2010/08/15/zend-api%E6%89%A9%E5%B1%95%E7%9A%84php%E5%AF%B9%E8%B1%A1%E7%9A%84autoload%E5%B7%A5%E5%85%B7/

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载