单例模式的PHP实现网上有很多,先贴一个实现代码,然后讲讲自己的理解。

  1. class singleton {
  2.     public $var = '';
  3.     private static $instance;

  4.     private function __construct(){
  5.     
  6.     }

  7.     private function __clone(){
  8.         return false;
  9.     }

  10.     public static function getInstance(){
  11.         if(! (self::$instance instanceof self)){
  12.             self::$instance = new self();
  13.         }
  14.         return self::$instance;
  15.     }

  16.     public function getData(){

  17.     }
  18. }
首先把类的构造函数设计为私有模式,这样,当从外部创建对象的时候,即:
$singletonObj = new singleton();
由于访问控制的原因,会报PHP error。所以这里就控制了只能从内部去控制对象的创建。

getInstance()
方法实现了类对象只能为单例,因为该方法首先会判定是否已经存在了一个类的实例,
如果存在则返回已经创建的实例,不存在则创建新的实例,并且保存到类的静态私有变量 $instance ,以用于下次判定实例是否已经存在。
所以,单例模式实现下创建对象应该是这样的:
$singletonObj = singleton::getInstance();

而把__clone方法设置为私有,是为了防止对象的复制。

以上,通过面对对象及语言本身的一些特点,就可以实现单例模式,
那什么时候可以用到这种设计模式呢?我来说一个我使用到的场景,

很多时候我们需要调用别的接口和服务来获取一些信息,可能还要多次调用同一个接口和服务,
然后一次请求的处理过程中,去调用别的接口和服务获取到的信息都是一致的,所以调用一次足以,否则就是浪费时间。
当然肯定能想到,把获取到的信息放到一个全局变量去保存,全局变量容易造成混乱,也不好维护,万不得已的情况下,我个人认为不值得推荐去用。

我们来看看单例模式怎么实现,
在上面的代码中我们可以设置一个类变量$var,初始化一个空字符串。
而getData()方法是去调别的接口获取数据,然后保存到$var中。

首先我们创建对象:
$singletonObj = singleton::getInstance();
然后我们判断 $singletonObj->var是否为空字符串,如果非空说明已经取过了数据,而如果为空,就调用
getData()方法去获取数据,这样可以保证一次请求过程中,只会去调用一次别的接口。

整体上看,就是在创建对象时,做了一些控制,我的想法是,由此可以做一个扩展,例如可能我们需要在某些条件下,才需要创建新的对象。
可以通过创建对象时传入参数,然后对参数做一些条件的判定,以确定是否创建新的对象,还是去返回已经存在的对象。


理论的东西只有去实践了,才能更好的去理解,以上是我现在对单例模式的简单理解,欢迎交流。

10-09 10:18