标签:
<!--
[单例模式] 当一个类的所有实例不需要不同时,可以设计成单例模式(人的实例化可能有很多种,但是数据库配置只有一种配置方法,只需要一个实例)
含义:整个系统中(整个进程中)单例类只有一个实例(对象)
特点:
一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
意义(生成单例模式的原因):
可以避免大量的new 操作消耗的资源
可以实现用一个类来全局控制某些配置信息
便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中
单例模式的实现
问题1:只能有一个实例,new是罪恶的根源,想办法让外部不能new如何解决?
解决方法:通过将构造方法,保护或私有化,外部即不能生成实例了。
2
问题2:不能new了,那不成0例模式了吗?那总得想办法生成一个实例吧?
解决方法:既然在外部不能new了,内部可以new啊,所以决定在内部通过静态方法new一个实例。
3
问题3:现在有实例了,但如果外部调用静态方法生成实例,就大于一个对象了。 如何防止呢?
解决方法:在内部将这个实例保存下来,并做判断。
4
问题4:如果继承一下,通过子类new对象,就大于一个对象了,如何解决?
解决方法:利用关键字“final“修饰生成实例的方法,则该方法不能被重载了
5
问题5:在外部通过clone函数克隆一个对象,则又大于一个对象了,如何解决?
解决方法:利用__clone魔术方法 解决此问题。
步骤总结:
1.定义一个类
2.定义类的受保护的(私有)构造函数
3.在类的内部定义生成类的唯一实例的方法,并用进行声明以防被子类重载
4.利用__clone()方法方法对象克隆
防外部new,防重载,防克隆
应用场景:
数据库配置类,只需要一个实例就行了,因为整个系统只需要这一个数据库,即使允许多次实例化,每个实例的属性和方法也是一样的,这里为了避免多次实例化浪费资源,就可以设计成单例模式
-->
<?php /** * Created by PhpStorm. * User: hollis * Date: 2016/7/31 * Time: 16:33 */ header("content-type:text/html;charset=utf8;"); //定义一个单例类 class single { //定义一个静态属性用于存储唯一的实例 static public $object = null; //定义一个受保护(或私有)的构造函数,避免外部实例化单例类 protected function __construct() { } //定义一个静态方法,生成唯一实例,final保证了此方法不会被子类重载 final static function NewOb() { //判断$object对象是否已经是单例类的实例(是否已经在此类实例化过了),如果已经实例化,则直接返回实例,不再进行实例化了(保证了只有一个实例),如果没有实例化过则实例化且返回实例 if (self::$object instanceof self) { return self::$object; } self::$object = new self(); return self::$object; } //__colone 方法 在克隆对象前自动运行,所以只要在这里阻止克隆,则无法运行到克隆对象的代码了 public function __clone() { trigger_error(‘Clone is not allow!‘,E_USER_ERROR); } } $t1 = single::NewOb(); $t2 = single::NewOb(); $t3 = clone $t2; if ($t1 === $t2) { echo ‘是一个对象<br />‘; } else { echo ‘不是一个对象<br />‘; } if ($t3 === $t2) { echo ‘是一个对象<br />‘; } else { echo ‘不是一个对象<br />‘; } //结果:保证了这个系统只存在一个实例 ?>
标签:
原文地址:http://www.cnblogs.com/hollis/p/5723636.html