单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。
通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的方法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他的实例可以被创建,并且它可以提供一个访问该实例的方法。
在它的核心结构中包含一个被称为特殊的单例。通过单例模式可以保证系统中一个类只有一个实例,即一个类只有一个对象实例。
要点:
- 一个类只有一个对象
- 必须是自动创建这个类的对象
- 整个系统只有这一个对象
从具体的实现角度来讲,需要保证一下三点: - 单例模式的类只提供私有的构造函数
- 类定义中含有一个该类的静态私有属性
- 该类提供了一个静态的公有函数用于创建或者获取它本身的静态私有对象
- 该类需要有一个私有的 clone 方法,防止被克隆
优点:
- 单例控制
单例模式会阻止其他对象实例化其自身的单例对象副本,从而确保所有的对象都访问唯一实例。 - 灵活
因为类控制了实例化过程,所以类可以灵活的变更类的实例化过程。
缺点:
- 开销
虽然数量很少,但如果每次对象请求引用都要检查类是否存在实例化对象,将扔需要一些开销,可以通过静态化方法解决做个问题。 - 开发混淆
使用单例对象时,开发人员必须记住不能使用 new 关键字实例化对象。
php单例模式实例:
class Single
{
static private $instance; // 私有静态属性用以保存对象
private $config;
//私有属性的构造方法 防止被 new
private function __construct ($config)
{
$this ->config = $config;
}
//私有属性的克隆方法 防止被克隆
private function __clone ()
{
}
//静态方法 用以实例化调用
static public function instance($config)
{
if (!self::$instance instanceof self)
{
self::$instance = new self($config);
}
return self::$instance;
}
}
//初始化对象
$single_case = Single::instance("测试实例化");
实例2:
class Database{
//四个私有,一个共有
//用于保存当前实例化后的对象
private static $instance = null;
//数据库连接句柄
private $db=null;
//构造方法生命为私有方法,禁止外部使用
private function __construct($a=''){
$this->db=$a;
}
//获取当前容器的实例(单例)
public static function getInstance($a=''){
if(self::$instance==null){
self::$instance =new self($a);
}
return self::instance;
}
//获取db
public function db(){
return $this->db;
}
//生命私有方法,禁止克隆对象
private function __clone(){}
//禁止重建对象
private function __wakeup(){}
}
$a='222222222222222222222';
$db1=Database::getInstance($a);
var_dump($db1);
$db2=Database::getInstance($a);
var_dump($db2);
$db3=Database::getInstance($a);
var_dump($db3);
注意:实用类的静态方法,类似于Math类,和单例模式很类似,实用类通常也会采用私有化的构造方法来避免其有实例。但是他们还是有很多不同的,比如实用类不保存状态,仅提供一些静态的方法或者事静态的属性让你使用,而单例类是有状态的。实用类不能用于继承状态,而单例虽然实例唯一,却是可以有子类来继承。实用类只不过是一些方法属性的集合,而单例却是有着唯一的对象实例。