单例模式是想实现一个类在系统中只有一个实例的解决方法,在实际的开发中,许多场景需要这样的单例,或者是为了提高性能减少开销也需要这样设计。
单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
应用实例:1、一个党只能有一个主席。 2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。 3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
优点:1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如网站首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景:1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
下边是PHP写的一个单例模式的例子:
<?php
class DataBaseConnection{
//定义私有静态变量,不能通过实例对象来访问
private static $_instance;
//测试变量
public $DataType;
//私有构造和克隆方法,防止new对象
private function __construct(){
}
private function __clone(){
}
//唯一访问入口,返回单例对象
public static function GetInstance(){
//如果没有实例化,则new一个,然后返回
if (self::$_instance===null)
{
self::$_instance = new self();
}
return self::$_instance;
}
//测试方法
public function SetDbType($DataType)
{
$this->DataType = $DataType;
}
public function GetDbType()
{
echo "DataBase is ".$this->DataType;
}
}
//调用。不能再用以前那种new对象来调用了,需要用类来调取静态方法
$DB = DataBaseConnection::GetInstance();
$DB->SetDbType("Oracle");
$DB->GetDbType();
?>