- class singleton {
- public $var = '';
- private static $instance;
- private function __construct(){
-
- }
- private function __clone(){
- return false;
- }
- public static function getInstance(){
- if(! (self::$instance instanceof self)){
- self::$instance = new self();
- }
- return self::$instance;
- }
- public function getData(){
- }
- }
$singletonObj = new singleton();
由于访问控制的原因,会报PHP error。所以这里就控制了只能从内部去控制对象的创建。
而getInstance()方法实现了类对象只能为单例,因为该方法首先会判定是否已经存在了一个类的实例,
如果存在则返回已经创建的实例,不存在则创建新的实例,并且保存到类的静态私有变量 $instance ,以用于下次判定实例是否已经存在。
所以,单例模式实现下创建对象应该是这样的:
$singletonObj = singleton::getInstance();
而把__clone方法设置为私有,是为了防止对象的复制。
以上,通过面对对象及语言本身的一些特点,就可以实现单例模式,
那什么时候可以用到这种设计模式呢?我来说一个我使用到的场景,
很多时候我们需要调用别的接口和服务来获取一些信息,可能还要多次调用同一个接口和服务,
然后一次请求的处理过程中,去调用别的接口和服务获取到的信息都是一致的,所以调用一次足以,否则就是浪费时间。
当然肯定能想到,把获取到的信息放到一个全局变量去保存,全局变量容易造成混乱,也不好维护,万不得已的情况下,我个人认为不值得推荐去用。
我们来看看单例模式怎么实现,
在上面的代码中我们可以设置一个类变量$var,初始化一个空字符串。
而getData()方法是去调别的接口获取数据,然后保存到$var中。
首先我们创建对象:
$singletonObj = singleton::getInstance();
然后我们判断 $singletonObj->var是否为空字符串,如果非空说明已经取过了数据,而如果为空,就调用
getData()方法去获取数据,这样可以保证一次请求过程中,只会去调用一次别的接口。
整体上看,就是在创建对象时,做了一些控制,我的想法是,由此可以做一个扩展,例如可能我们需要在某些条件下,才需要创建新的对象。
可以通过创建对象时传入参数,然后对参数做一些条件的判定,以确定是否创建新的对象,还是去返回已经存在的对象。
理论的东西只有去实践了,才能更好的去理解,以上是我现在对单例模式的简单理解,欢迎交流。