单例模式Singleton:
意图:
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
动机:
对于一些类来说,只有一个实例是很重要的。虽然系统中可以由很多打印机,但是只有一个打印假脱机(print
spooler),只应该有一个文件系统和一个窗口管理工具。一个数字滤波器也只能有一个A/D转换器。
实现方式:
让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建(即通过街区创建新对象的请求),并且它可以提供一个访问该实例的方法。
使用场景:
当类只能有一个实例而且客户可以从一个众所周知的访问点访问它。
当这个唯一实例应该是通过子类化可扩展的,并且客户无需更改代码就能使用一个扩展的实例时。
资源共享的情况下,避免由于资源操作时导致的性能或损耗等,如日志文件等。
控制资源的情况下,方便资源之间的互相通信。如线程池等。
常见场景:
windows的Recycle
Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
优点:
对唯一实例的受控访问,因为Singleton类封装它的唯一实例,所以它可能严格控制客户怎样以及何时访问它。
缩小命名空间
允许对操作和表示的精华
允许可变数目的实例
比类操作更灵活
示例代码:
class SingleTon{
private static SingleTon instance = new SingleTon();
private SingleTon() {//构造函数为私有=>不能在其他类中使用new的方式构造SingleTon对象
// TODO Auto-generated constructor stub
}
public static SingleTon getInstance() {
return instance;
}
private String name;//姓名
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Multi{
public Multi() {
// TODO Auto-generated constructor stub
}
private String name;//姓名
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class SingleTonDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("单例模式");
SingleTon sTon1 = SingleTon.getInstance();
SingleTon sTon2 = SingleTon.getInstance();
sTon1.setName("HelloJomo");
System.out.println(sTon2.getName());
System.out.println(sTon1==sTon2);
//对比实验
System.out.println("非单例模式");
Multi multi1 = new Multi();
Multi multi2 = new Multi();
multi1.setName("HelloJomo");
System.out.println(multi2.getName());
System.out.println(multi1==multi2);
}
}
实验结果:
单例模式
HelloJomo
true
非单例模式
null
false