什么是Singleton模式?
Sigleton模式的设计意图是:保证一个类只有一个对象实例,并提供一个访问对象实例的全局访问点。
如果我们想实现一个全局范围可见的对象以替代麻烦缠身的全局变量,那么最好的做法就是将数据封装在一个特殊的类中。这个严格管理数据的创建过程以保证数据的唯一性,同时不允许程序员随意创建该类的对象实例。虽然不能通过类的构造函数获得对象实例,但可以通过该类提供的静态成员函数得到该类唯一的对象实例的指针或引用。
Singleton模式和全局变量有什么区别:
全局变量的问题:
(1)变量名冲突:必须小心维护变量名规则,所有工程师在开发代码时,每遇到一个全局变量,都必须仔细分辨该变量究竟属于哪个模块、哪个程序。
(2)耦合度难题:全局变量实际上增加了函数与模块之间的耦合度。用通俗的话说,需要访问某个特定全局变量的多个函数被该变量牢牢地“粘结”在一起,成为拆不散的一团乱麻。
(3)单个实体问题:全局变量不能阻止程序员定义一个类的多个对象实例。如果没有其它技术手段帮助,保证一个类只有单个实例就全靠程序员的自觉。
(4)初始化顺序:全局变量不能保证相互之间遵循特定的初始化顺序,这完全由编译器决定。对于类的对象实例,构造函数被调用的顺序有时就显得非常重要。
(5)多线程访问:当多个并发的线程都需要访问某些全局变量时,我们必须使用各种同步机制,小心地保护这些全局变量,以免陷入并发冲突的泥潭。
singleton模式的优点:
1)跨平台:使用合适的中间件,可以把singleton模式扩展为跨多个JVM和多个计算机工作。
2)适用于任何类:只需把一个类的构造函数变成私有的,并且在其中增加相应的静态函数和变量,就可以把这个类变成singleton。
3)可以透过派生创建:给定一个类,可以创建它的一个singleton之类。
4)延迟求值:如果singleton从未使用过,那么就决不会创建它。
singleton模式的代价 :
1)摧毁方法未定义:没有好的方法去摧毁一个singleton,或者解除其职责。即使添加一个decommission方法把theInstance置为null,系统中的其他模块仍然持有对该singleton实例的应用。这样,随后对Instance方法的调用会创建另外一个实例,致使同时存在两个实例。这个问题在C++中尤为严重,应为实例可以被摧毁,可能会导致去提领一个已被摧毁的对象。
2)不能继承:从singleton类派生出来的类并不是singleton。如果要使其成为singleton,必须要增加所需的静态函数和变量。
3)效率问题:每次调用Instance方法都会执行if语句。就大多数调用而言,if语句是多余的。
4)不透明性:singleton的使用者知道它们正在使用一个singleton,因为它们必须要调用Instance方法。
Singleton模式示例代码:
class Singleton
{
private static Singleton _instance = null; // 静态对象,只初始化一次!
privateSingleton(){}//构造函数为private
public static Singleton Instance()
{
if(_instance==null) // 保证每次只能实例化一个对象
{
_instance=new Singleton();
return_instance;
}
}
}
运用singleton模式:
多个应用程序都需要打印log信息,比如向同一个控制台或者同一个文件输出。此时是需要用到单一模式的,在多个进程或线程中,只能生成一个类的对象实例。