单例模式是想实现一个类在系统中只有一个实例的解决方法,在实际的开发中,许多场景需要这样的单例,或者是为了提高性能减少开销也需要这样设计。
单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
应用实例: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(); ?>