php 单例模式原理,再谈PHP单例模式Singleton

单例模式属于创建型模式,它是设计模式中最简单的一种模式,当然它的使用也是无处不在的。

单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。

当需要控制一个类的实例数量,且调用者可以从一个公共的众所周知的访问点访问时,我们就可以考虑使用单例模式了。

我们用 UML 来设计单例模式,当然在以后的设计模式的设计部分,我们都将采用 UML 来描述我们的设计,这样就更为形象化了。

c2b1c04dac25bfd6486973d9f62e0b76.png

从 UML 设计图中我们可以看出,为了让一个类只有一个实例,它必须创建一个静态变量,然后我们用一个公共静态的 Instance() 的方法来创建它,但是为了避免这个类自身的构造函数可以创建对象,我们将构造函数设置成 protected 或者 private,这样外部就只能通过 Instance() 的方法来创建一个静态的 Singleton 类。看来这样我们达到了我们的目的,接下来我们看代码:

public class Singleton {

private static Singleton instance;

protected Singleton()

public static Singleton Instance() {

if(instance != null) instance = new Singleton();

return instance;

}

}

由此看来,实现单例模式我们可以做下列几步:

在类中创建一个静态变量,变量类型为当前类;

在类中创建一个公共的静态方法,让用户可以通过此方法创建此类的静态对象;

最后将构造函数设置为 protected 或者 private。

Program List:最简单的单例类

class Fruit

{

static private $_color;

private function __construct()

{

}

static public function singleton() {

return isset(self::$_color) ? self::$_color : self::$_color = new self();

}

}

?>

Program List:可扩展的单例类

一个可扩展的单例类看似不可能,但下面的程序很接近这种效果。

class Test extends Fruit {

public static function getInstance()

{

return Fruit::getSingleton(get_class());

}

}

?>

class Fruit {

/***********************

* HOW TO USE

*

* Inherit(extend) from Singleton and add getter:

*

* //public getter for singleton instance

* public static function getInstance(){

* return Singleton::getSingleton(get_class());

* }

*

*/

private static $instanceMap = array();

//protected getter for singleton instances

protected static function getSingleton($className)

{

if(!isset(self::$instanceMap[$className]))

{

$object = new $className;

//Make sure this object inherit from Singleton

if($object instanceof Fruit)

{

self::$instanceMap[$className] = $object;

}

else

{

throw SingletonException("Class '$className' do not inherit from Singleton!");

}

}

return self::$instanceMap[$className];

}

//protected constructor to prevent outside instantiation

protected function __construct(){

}

//denie cloning of singleton objects

public final function __clone(){

trigger_error('It is impossible to clone singleton', E_USER_ERROR);

}

}

?>

class Apple extends Fruit {

protected $rndId;

protected function __construct(){

$this->rndId = rand();

}

public function whatAmI(){

echo 'I am a Apple('.$this->rndId.')
';

}

public static function getInstance(){

return Fruit::getSingleton(get_class());

}

}

class GreenApple extends Apple {

public function whatAmI(){

echo 'I am a GreenApple('.$this->rndId.')
';

}

public static function getInstance(){

return Fruit::getSingleton(get_class());

}

}

$apple1 = Apple::getInstance();

$apple2 = GreenApple::getInstance();

$apple1->whatAmI();// should echo 'I am a A(some number)

$apple2->whatAmI();// should echo 'I am a B(some number)

$apple1 = Apple::getInstance();

$apple2 = GreenApple::getInstance();

$apple1->whatAmI();// should echo 'I am a A(same number as above)

$apple2->whatAmI();// should echo 'I am a B(same number as above)

// $a = new A();// this should fail

// $b = new B();// this should fail

?>

程序运行结果:

I am a Apple(4462)

I am a GreenApple(8207)

I am a Apple(4462)

I am a GreenApple(8207)

Program List:单例类与其派生类

class Fruit

{

// Hold an instance of the class

private static $instance;

// A private constructor; prevents direct creation of object

protected function __construct()

{

echo 'I am constructed';

}

// The singleton method

public static function singleton($classname = __CLASS__)

{

if (!isset(self::$instance)) {

self::$instance = new $classname;

}

return self::$instance;

}

}

class Apple extends Fruit {

public static function singleton()

{

return parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance.

}

public function showColor()

{

echo 'My Color is Red.';

}

}

$subclassInstance = Apple::singleton();

$subclassInstance->showColor();

?>

程序运行结果:

I am constructed

My Color is Red.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值