正在查看: 标记有标签 设计模式 的文章(第 1 页 / 共 3 篇)

PHP设计模式:Singleton单例模式

此文承接之前我在PHP中实现简单工厂抽象工厂的讨论,讨论一个广泛应用在OOP体系中的设计模式——Singleton模式。

Singleton Pattern(中文称单例模式),可以说是最容易理解的设计模式了,也充分体现了DRY (Don't Repeat Yourself)的思想。它的核心思想是:保证一个对象存在且仅允许存在一个实例,并提供一个全局访问方式[via]。

单例模式的运作模型是:当对象第一次被请求时,创建这个对象的实例;之后的每次请求,仅传递已创建实例的句柄。与单例模式相对应的模式叫做Prototype(Java平台下)或者叫SingleCall(.NET平台下),在此种模式下,每次请求一个对象,都将新建一个实例。

在WEB程序中应用单例模式的一个典型例子是数据库连接的创建:通过数据库句柄来连接数据库这一行为是独占的。换言之,在一个句柄尚未关闭之前,你无法第二次创建一个相同名称的句柄。然后在日常编码中,假设你希望在同一页面中操作由数据库传递回来的多组数据。此时如果采用传统的Prototype方式编程,为了程序的安全运行,你可能需要创建多个数据库链接句柄或者重复进行打开/关闭数据库连接的操作。显然,这样的操作会导致程序过度消耗一些不必要的资源。

在此场景下,我们可以运用单例模式来维护和共享同一个数据库句柄。优点有二:

1、提高了程序运行上的安全性。你不必过多的担心和考虑诸如数据库打开/关闭的问题。

2、避免了因创建多个连接导致的不必要资源浪费。垃圾回收机制仅需要对一个链接句柄进行操作。

当然,以上两个问题对于PHP来说并不是问题,PHP的垃圾回收机制就是,当一个页面执行完毕会自动清空所有资源和内存,这里面就包括数据库连接。

至此,可以总结出Singleton单例模式在WEB程序中的运用场合:

1、某些资源本身具有独占性,你不希望在多个地方重复创建对这个独占资源对象的实例。

2、你需要在一个对象的多个实例之间共享这个对象的状态(下面我会将此条规则进行代码举例)。

下面写一段小代码来演示PHP 5中Singleton的实现:

/***************************************************************************
 *              Singleton在PHP5中的实现
 *             
 *   @Author  :    Saturn
 *   @Contact: http://www.cnsaturn.com/
 ***************************************************************************/
class Singleton
{
 //此成员变量用来记录此对象的引用次数
 private $counter = 1;
 //注意这里是private,即禁止外部程序通过解析函数实例化对象
 private function __construct()
 { }
 //禁止克隆这个对象
 private function __clone() 
 { }
 //必须通过此方法得到对象的引用
 public static function getInstance()
 {
  static $instance = null;
  if($instance == null)
  {
   $instance = new Singleton();
  }
  return $instance;
 }
 
 public function getUsedCount()
 {
  return $this->counter++;
 }
 
}
//test test
echo Singleton::getInstance()->getUsedCount();//echo 1
echo Singleton::getInstance()->getUsedCount();//echo 2
echo Singleton::getInstance()->getUsedCount();//echo 3
$obj = new Singleton();//trigger fatal error
?>

此程序演示的是如何通过Singleton模式让多个引用能够同时共享此对象的某个状态,在这里是共享$counter。

注意,我们将解析函数的Scope设置成了private,这样做为了禁止通过解析函数实例化对象,而必须使用对象提供的静态化方法getInstance来获取对象的引用。

这个例子比较简单,但已经初步展示了单例模式的核心思想,仅起抛砖引玉的作用。

PHP设计模式:工厂模式之抽象工厂

上一篇中,我主要记录了工厂模式之一的简单工厂在PHP中的实现,这篇文章主要总结工厂模式的另一种形态:抽象工厂。

简单工厂中,工厂的角色是负责实例化具体对象,而在实际应用中这种情况却不很实用,主要原因是如果我们希望增加或去除这个工厂所能实例化的某个对象,则需要对工厂类进行直接修改,这显然违背了低耦合的宗旨。对于上一篇文章的例子来说,那就是:如果我们需要添加那个汽车工厂所能生成的汽车品牌,则需要修改工厂类的判断逻辑。

如何尽可能的降低耦合,从而达到非侵入式的设计逻辑?这里的非侵入式一次,是我从Spring中借用过来的概念,通俗来讲,就是去除和添加某个工厂的产品对象不影响整个程序的架构。

由此就引入了抽象工厂的思想。抽象工厂将面向接口编程的思想演绎的淋漓尽致,它的核心思想是:抽象工厂仅提供一个产品簇(同一类别的所有对象的接口抽象)的通用接口,而将实例化对象的任务交给遵循其标准的具体工厂来完成;具体工厂还可能生产出多个产品,此时还需要对产品定义一个接口,供具体工厂来生产具体产品。

举个例子,还是关于生产汽车的。汽车工厂经过一段时间的努力,现在已经发展装大了,于是做了两个决定:第一个决定是将生产汽车的过程分拆成两个阶段,分别是生成轮胎和除去轮胎的其他部分。另一个决定是,决定为每个汽车品牌单独建立一个汽车工厂。那么如何管理这些工厂,使他们既遵循第一个决定,又不相互干扰?解决办法就是:汽车总厂提供生产汽车的通用流程(第二条),这个流程两个子工厂都需要严格执行。同时,将具体生产的过程交给两个具体工厂,分别是Benz工厂和Audi工厂。这就是抽象工厂的设计思想的概念。

»阅读全文

PHP设计模式:工厂模式之简单工厂

要写出漂亮的代码,掌握一些常用的设计模式是很有必要的。这篇文章只是我将设计模式应用在OO PHP的系列学习(之前一直是在JAVA里面)笔记之一,如有不妥,就留言一起探讨。

根据设计模式的圣经GoF所写的Design Patterns: Elements of Reusable Object-Oriented Software一书的分类,工厂模式被归类在创建模式(Creational Pattern)之下。工厂模式作为一种创建模式,主要用于处理对象的创建,以适合不同场景[via]。

工厂模式又分为抽象工厂模式和工厂方法模式。

本文所讨论的简单工厂,又称作静态工厂方法,可以看作是工厂方法的一个特例。个人认为它是学习工厂模式最好的切入点。

工厂模式,正如其名,我们在实例化一个对象时,不是直接实例化具体的对象,而是通过工厂这个接口来实现。通俗的说,作为消费者(某个对象A),我们在需要消费(调用)某个具体产品(其他对象B)时,不需要了解这个产品(对象B)的制作过程(实现过程),只需要直接拿这个产品来用即可。而具体的这个产品的生成(对象的实例化)过程,由工厂实现。

可见,工厂模式可以在降低对象间的关联(耦合度降低),并能够隐藏具体产品的实现过程。因为整个调用过程是面向接口的。

»阅读全文