黑马程序猿-单例模式
单例设计模式
通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问。从而方便对实例个数的控制并节约系统资源。假设希望在系统中某个类的对象仅仅能存在一个,单例模式是最好的解决方式。显然单例模式的要点有三个:一是某个类仅仅能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
解决的问题:保证一个类在内存中的对象唯一性。
比方:多程序读取一个配置文件时,建议配置文件封装成对象。会方便操作当中数据,又要保证多个程序读到的是同一个配置文件对象。就须要该配置文件对象在内存中是唯一的。
Runtime()方法就是单例设计模式进行设计的。
怎样保证对象唯一性呢?
思想:
1,不让其它程序创建该类对象。
2。在本类中创建一个本类对象。
3,对外提供方法。让其它程序获取这个对象。
步骤:
1。由于创建对象都须要构造函数初始化。仅仅要将本类中的构造函数私有化,其它程序就无法再创建该类对象;
2,就在类中创建一个本类的对象;
3,定义一个方法。返回该对象,让其它程序能够通过方法就得到本类对象。
(作用:可控)
代码体现:
1,私有化构造函数;
2。创建私有并静态的本类对象;
3,定义公有并静态的方法,返回该对象。
单例的创建方式有两种:
懒汉式:用户调用方法的时候创建对象
饿汉式:在静态代码块中已经创建好了对象
---------------------------------------------
//饿汉式
class Single{
private Single(){} //私有化构造函数。
private static Single s = new Single(); //创建私有并静态的本类对象。
public static Single getInstance(){ //定义公有并静态的方法,返回该对象。
return s;
}
}
---------------------------------------------
//懒汉式:延迟载入方式。
class Single2{
private Single2(){} //私有化构造函数
private static Single2 s = null;//创建null对象。
public static synchronized Single2 getInstance(){ //synchronized保证每次仅仅有一个线程在运行方法中的代码,避免创建多了对象
if(s==null)
s = new Single2();//创建私有并静态的本类对象。
return s;
}
}
双重锁的形式
public class Singleton{
private static Singleton instance=null;
private Singleton(){
//dosomething
}
public static Singleton getInstance(){
if(instance==null){
synchronized(Singleton.class){
if(null==instance){
instance=new Singleton();
}
}
}
return instance;
}
}//这个模式将同步内容下方到if内部。提高了运行的效率。不必每次获取对象时都进行同步,仅仅有第一次才同步,创建了以后就不是必需了。
实现要点
Singleton模式是限制而不是改进类的创建。
Singleton类中的实例构造器能够设置为Protected以同意子类派生。
Singleton模式一般不要支持Icloneable接口。由于这可能导致多个对象实例,与Singleton模式的初衷违背。
Singleton模式一般不要支持序列化。这也有可能导致多个对象实例。这也与Singleton模式的初衷违背。
Singleton仅仅考虑了对象创建的管理。没有考虑到销毁的管理,就支持垃圾回收的平台和对象的开销来讲,我们一般不是必需对其销毁进行特殊的管理。
理解和扩展Singleton模式的核心是“怎样控制用户使用new对一个类的构造器的随意调用”。
能够非常easy的改动一个Singleton,使它有少数几个实例,这样做是同意的并且是有意义的。
长处
实例控制:Singleton 会阻止其它对象实例化其自己的 Singleton 对象的副本,从而确保全部对象都訪问唯一实例
灵活性:由于类控制了实例化过程。所以类能够更加灵活改动实例化过程
缺点
开销:尽管数量非常少,但假设每次对象请求引用时都要检查是否存在类的实例,将仍然须要一些开销。能够通过使用静态初始化解决此问题。上面的实现方式中已经说过了。
可能的开发混淆:使用 singleton 对象(尤其在类库中定义的对象)时。开发者必须记住自己不能使用 new keyword实例化对象。
由于可能无法訪问库源码,因此应用程序开发者可能会意外发现自己无法直接实例化此类。
对象的生存期:Singleton 不能解决删除单个对象的问题。
在提供内存管理的语言中(比如基于 .NET Framework 的语言),仅仅有 Singleton 类可以导致实例被取消分配,由于它包括对该实例的私有引用。在某些语言中(如 C++),其它类可以删除
对象实例。但这样会导致 Singleton 类中出现悬浮引用。
适用性
当类仅仅能有一个实例并且客户能够从一个众所周知的訪问点訪问它时。
当这个唯一实例应该是通过子类化可扩展的,而且客户应该无需更改代码就能使用一个扩展的实例时。
代码演示样例: