PHP常见设计模式之单例模式
什么是单例模式
当我们实例化一个对象时,他可以确保我们实例化的这个类将仅有一个实例,并且我们在我们的代码中的任何地方都可以轻易的召回相同的对象。
就是说,当我们使用单例模式第一次调用对象时,他就会被实例化,之后每一次调用都将会返回同一个对象。
单例模式通常用于对象,它代表在应用程序不同部分被再三使用的资源,而且始终为同一对象。
常见的示例包括数据库连接和配置信息。
为什么要使用单例模式
单例模式最重要的方面就是在于对创建示例的限制能力。如果不这样做的话,应用程序中同一个对象可能会被创建多个实例,可能会造成资源的浪费。
实现方式
通过创建私有的构造器来实现限制对象创建实例的能力。示例,
<?php
class Database extend PDO{
//私有静态变量,用来保存单例实例
private static $_instance = null;
//私有构造函数,保证这个类只能被本省的静态发放实例化
private function _contruct(){
//调用PDO的构造函数
parent::_contruct(APP_DB_DSN, APP_DB_USER, APP_DB_PWD);
}
//获得单例实例的方法。如果实例已经存在,则直接返回;否则先构造一个,然后返回;
public static function getInstance(){
if(!(self::$_instance instanceof Database)){
self::$_instance = new Database();
}
return self::$_instance;
}
}
实现单例的三个关键点:
- 使用一个静态成员来保持一个单例实例。在这个例子中,我们有一个私有的DB::$_instance属性。
- 然后,一个私有的构造函数将决定这个类只能被本身所包含的静态方法实例化。
- DB::getInstance()静态方法将用于数据库类。当他被调用时,DB::getInstance()将实例化一个Database类的对象并将这个对象指定给DB::$_instance属性,然后返回这个对象,或只返回先前已经实例化的对象。
我们之所以使用单例模式,是因为静态方法可以在全局范围内被访问,无论哪里,当我们需要一个数据库连接时,只需要调用DB::getInstance()即可。
使用单例模式的问题
尽管单例思想很伟大,但当我们确实需要多个实例的时候,其局限性就显而易见。
比如,我们拆分了数据库之后,就需要在不同的服务器上进行读写操作。而这时单例就满足不了我们的需求了。
所以单例模式不恰当的使用就会抑制自身的发展和重用。所以当想通过一个类创建两个实例,我们可以考虑通过注册表模式来实现。