每次面试都会被问到什么是单例模式,写代码实现一个单例模式,在什么情况下会使用单例模式,单例模式的作用是什么?你有没有每次面试都被问住的,是时候好好研究研究单例模式啦。
一、什么是单例模式?
单例模式指的是在整个应用中只有一个对象实例的设计模式。说白了就是说一个类只能实例化一次。
二、为什么要使用单例模式?
php常常和数据库打交道,如果在应用中如果频繁建立连接对象,进行new操作的话,会消耗大料的系统内存资源,这并不是我们希望看到的。再则,在团队合作项目中,单例模式可以有效避免不同程序员new自己的对象,造成人为的系统消耗。
三、单例模式的实现
在知乎上看到一哥们写的很容易记,顺手拿来了若有违权,可以联系删除
/* 单例设计模式 (单态) 定义: 一个类 只能允许有 一个对象存在. 1.不让进: 使类不能被实例化 2.留后门: 设置静态方法 3.给对象: 在静态方法里实例化该类 4.判初夜: 判断是否是 第一次产生该类的对象 5.设静态: 静态方法里 要使用静态属性 */ /*//1.不让进: 使类不能被实例化----------------- class Test { // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } }*/ /*//2.留后门: 设置静态方法-------------------- class Test { // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } //后门 public static function getObject() { echo "啊,我是后门,进吧!<br>"; } }*/ /*//3.给对象: 在静态方法里实例化该类------------------ class Test { // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } //后门 public static function getObject() { echo "啊,我是后门,进吧!<br>"; return new self();//实例化一个对象给你 } }*/ /*//4.判初夜: 判断是否是 第一次产生该类的对象------------------ class Test { private $obj = null;//属性值为对象,默认为null // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } //后门 public static function getObject() { echo "啊,我是后门,进吧!<br>"; if ($this->obj === null) { $this->obj = new self();//实例化一个对象 } //返回的属性 其实就是本对象 return $this->obj; } }*/ //5.设静态: 静态方法里 要使用静态属性------------------ class Test { private static $obj = null;//属性值为对象,默认为null // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } //后门 public static function getObject() { echo "啊,我是后门,进吧!<br>"; if (self::$obj === null) { self::$obj = new self();//实例化一个对象 } //返回的属性 其实就是本对象 return self::$obj; } } /*Test::getObject();//使用静态方法访问该类里的方法 exit;*/ $t1 = Test::getObject(); $t2 = Test::getObject(); $t3 = Test::getObject(); $t4 = Test::getObject(); $t5 = Test::getObject(); $t6 = Test::getObject(); $t7 = Test::getObject(); $t8 = Test::getObject(); //判断 两个对象 是否是同一个对象 if (t1 === t6) { echo "哦, Yes! 是同一个实例<br>"; } else { echo "哦, No! 不是同一个实例<br>"; }
从上面的代码可以看出来,PHP的单例模式实现要求:
1、一个private的__construct是必须的,单例类不能在其它类中实例化,只能被自身实例化;
2、拥有一个保存类的实例的静态成员变量;
3、一个静态的公共方法用于实例化这个类,并访问这个类的实例;