和我一起学设计模式(—),学设计模式
程序员文章站
2022-05-18 14:10:03
...
和我一起学设计模式(—),学设计模式
今天我们一起来学习单例模式:
学一个模式,我们总要知道应用的场景吧。不然,就好比学一门武功招式,若不知道在何种情况下使用,岂不是枉费功夫呀。
对于单例模式,最常见的一个应用就是数据库连接。如果每打开一个网页,就建一个链接,那这种销耗是很大的一个浪费。所以我们需要用单例模式来确保系统只有在必要的时候才建立新连接。
如果用伪代码来描述单例模式,可以这样写:
if(连接存在){
返回该链接
}else{
建立一个新链接
}
但是这样实现显然是有问题的,这个链接要怎么保存,才可以被外部访问,同时又可以不被外部破坏。这个如果是用php来实现的话,是很容易的。我们一起来看一段代码:
//get data class class DB { private $_db; private static $_instance; private function __construct(){ $DSN = '../../content/xxtebook.db'; $this->_db = new PDO('sqlite:'.$DSN); } //初始化数据库连接 public static function initDB(){ if(! (self::$_instance instanceof self)){ self::$_instance = new self(); } return self::$_instance; } //其它方法 }
为什么要把构造函数进行私有化呢?这个问题问的很好,欢迎大家提出这样的疑问哈。
首先,做为单例,就是要避免被外部意外的创建新的实例。通过内部的方法进行实例的创建工作,可以确保这一点。而且内部方法访问内部的变量,具有先天性的优势。
其实我们可以把实例的结时保存在类的内部,这样下次在检到这个值的存在时,可以直接取出使用,而不需要再重新创建。
当然,我看到有些书上,做了一个空的 __clone(){}方法,防止克隆,这是很好的。锦上添花的事情,我就留到具体的项目上去做了。
最后我们来看看怎么用这个单例:
$db = DB::initDB(); //$db->somMethod();
是不是非常的简单呢。
另外对于哪些方法用静态,哪些方法不用,我的想法就是,如果方法内部要访问$this变量的,那么就不应当用静态方法,反之则可以用静态。也就是说,静态方法不需要通过例实对象就可以使用。
下一次我们再一起学习工厂模式