[转自]http://www.cnblogs.com/kamome/archive/2010/02/02/1661605.html
目录
体会1:static不能称霸全宇宙。
体会2:逻辑上单一的对象应该应用单例模式。
体会3:多线程与单例。
体会4:单例串行化/串流化的关系。
体会5:单例模式子类化的问题。
体会1:static不能称霸全宇宙。
很多人以为,static无敌。错的,static有时无敌,什么时候呢?如果是public static final N CONSTANT=xxx;那么这是非常好的一种代码风格,因为这代表了一系列该类别通用的常数。这里的N除了几种“原生类型”(primitive type),例如int,char等之外,还包括了“不可变类别”(immutable class),例如String。在上述两种情况之外,都尽量要避免这种乱用static的风格。例如public static MyObject myObject;这种使用破坏了类的封装性。
此外,static方法的使用也很有讲究,只有在实现“纯工具类”(例如Math类)或者实现“简单工厂”逻辑的时候,可以容忍public static方法的存在。如果不分析具体情况,乱用共有静态方法,则退回到了面向过程的老路,为什么呢?static方法所处的静态环境没有办法存取实例变量,这就逼着我们把所有本来应该为实例变量的域声明为静态域,整个一个类退化为一个“具有若干成员和函数指针的结构体(struct)”,不是吗?
体会2:逻辑上单一的对象应该应用单例模式。
注册表、设备驱动程序、线程池、窗口管理器等等这些概念,如果我们允许多个实例存在,必然在整个系统之间引发混乱,所以应该引入单例模式。这一点暂时不多说,以后补充。
体会3:多线程与单例。
在多线程环境下应用单例,有以下几种方法:
1.将整个getInstance方法设定为同步函数,并在其中进行“惰性初始化”。如果构建该对象的花销远远大于获取同步锁的花销,那么此种方式非常值得。
2.在声明完单例引用之后立即实例化。如果构建该对象的花销远远小于获取同步锁的花销,那么此种方式非常值得。
3.“双重检测锁”模式。如182页所示,这种看似“聪明”的方式,其实有着巨大的漏洞。简单的说,在1.5之前的JVM中,代码会进行“重整”,单例引用uniqueInstance有时尽管不为null,但是此时所引用的那个“单例对象”,并没有被完全初始化。也就是new Singleton()函数未正式完成其工作之前,JVM可以根据Java规范,重整代码,使得uniqueInstance先获得这个“单例对象”的引用,这样一来,第二个线程直接判定单例已完成实例化,故接下来的客户代码会直接使用单例对象的数据,但是有些数据并没有被正确的初始化,因为new Singleton()尚未正式完成。
我是泛泛而谈,具体的信息请参阅这篇文章:
The “Double-Checked Locking is Broken” Declaration
4.既想“惰性初始化”,又想避免“获取同步锁开销”的方法。大名鼎鼎的Joshua Bloch在神作《Effective Java》中,建议1.5及以后的版本用一个“含有单一枚举值的enum来实现单例”,并举例如下。
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
这就是巧妙地运用了Java规范中关于enum初始化的特性。
在1.5之前,Bloch推荐的方法是用一个“辅助占位类”来包容这个实例,如下:
// Lazy initialization holder class idiom for static fields
private static class FieldHolder {
static final FieldType field = computeFieldValue();
}
static FieldType getField() { return FieldHolder.field; }
同样也是运用了Java规范中关于类加载的相关知识。
体会4:单例串行化/串流化的关系。
这个问题比较复杂,我暂时还没有研究,但是提醒大家,要记得重写读取解析函数,再引用一次Bloch的代码:
// readResolve method to preserve singleton property
private Object readResolve() {
// Return the one true Elvis and let the garbage collector
// take care of the Elvis impersonator.
return INSTANCE;
}
这个问题将来我会单独讲解,这里先放一放吧。
体会5:单例模式子类化的问题。
有时我们可能要对某单例类别子类化,例如“窗口管理器”应该是一个单例,但是如果这是一个抽象类,有不同的子类去实现,每次系统启动的时候,有且只有一个子类窗口管理器被实例化,这就需要处理单例模式和子类化之间的问题了。
问题在于,单例类的构造函数是private,为了能被子类化,至少应该是“包缺省”级别的,但这样一来,就没办法控制构造函数的使用了。看了本书和《设计模式》的讨论,都说在基类设置一个注册表的机制。本人认为这样做不一定最好。我采取的做法如下:
public abstract class MySingleton{
private static MySingleton instance;
MySingleton(){
if (instance==null){
instance=this;
}else{
throw new IllegalStateException(
"There is already a singleton instantiated: "+instance);
}
}
public static MySingleton getInstance(){
return instance;
}
}
public final class SubSingleton extends MySingleton{
}
这样我们把第一次初始化单例的任务交给一个“简单工厂”。例如在系统启动的时候,调用singletonFactory.createSingleton(),此后,我们就可以通过MySingleton.getInstance()来获得正确的单例对象引用了。下次系统启动的时候,单例工厂会再去初始化正确的单例。
分享到:
相关推荐
【深入浅出单例Singleton模式】 单例模式是一种在软件设计中常见的设计模式,它的核心目标是确保一个类只有一个实例,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常用于控制资源的共享,如全局...
单例模式(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于需要全局共享资源的场景,比如配置管理、日志记录等。 单例模式的组成 私有构造函数:防止外部...
深入浅出设计模式附书源码Java版源代码,是面向Java开发者的宝贵资源,旨在帮助他们理解和实践各种设计模式。这本书籍的源代码提供了实际的示例,使得学习过程更具互动性和实践性。 设计模式的核心思想是将常见的...
### 深入浅出设计模式之单件模式 #### 一、单件模式概述 单件模式(Singleton Pattern)是软件设计模式中最为常见的一种,它的主要目标是确保某个类只有一个实例,并提供一个全局访问点。单件模式在很多情况下都...
《深入浅出设计模式》这个压缩包文件很可能是为了帮助读者理解和掌握设计模式的核心理念与应用场景,从而提升软件开发的效率和质量。 在软件开发过程中,设计模式如同一种通用的语言,让开发者能够快速交流复杂的...
《深入浅出设计模式》是一本关于软件设计的经典著作,主要涵盖了面向对象设计中的核心设计模式。这本书旨在帮助读者理解并掌握如何在实际编程中应用这些模式,提升代码的可维护性和可扩展性。设计模式是经过时间和...
本资料包包含“深入浅出设计模式 C++”的源码和相关教材,旨在帮助开发者理解和应用设计模式。 一、设计模式的重要性 设计模式不仅提供了可重用的代码结构,还促进了团队间的沟通和代码的可维护性。它们是经验丰富...
《HeadFirst设计模式》是一本深受开发者喜爱的经典书籍,它以独特的方式深入浅出地讲解了设计模式这一重要编程概念。设计模式是软件工程中经过实践验证的、解决常见问题的有效解决方案,对于提升代码可读性、可维护...
《深入浅出设计模式样章》是一本专为软件开发者准备的指南,旨在帮助读者理解和掌握设计模式这一核心编程概念。设计模式是软件工程中经过时间验证、在特定情境下解决常见问题的有效方法,它提供了可重用的解决方案,...
《深入浅出设计模式》是一本旨在帮助读者理解和掌握设计模式的书籍,适合那些希望深入研究设计模式的IT从业者。这本书可能与《HEAD FIRST设计模式》相辅相成,通过不同的讲解方式来帮助读者更全面地理解这一领域。 ...
《Head.First深入浅出设计模式》是一本专为初学者和有一定经验的程序员设计的书籍,旨在用直观、趣味的方式讲解复杂的设计模式概念。作者通过丰富的图表、幽默的插图和实际的编程示例,使得原本枯燥的理论变得生动...
《深入浅出设计模式源码 Java》是一本深入解析Java设计模式的著作,它通过易于理解的方式揭示了软件设计中的核心原则和模式。设计模式是软件工程中的宝贵经验总结,它们是解决常见问题的最佳实践,可以帮助开发者...
设计模式是软件工程中的一种重要概念,它是在特定情境下为解决常见问题而形成的一套最佳实践。在软件开发过程中,设计模式可以帮助我们构建可...因此,深入学习和掌握设计模式对于任何IT专业人士来说都是非常重要的。
根据提供的标题“深入浅出设计模式之与设计模式相处”以及描述“将《Head First 设计模式》(中文版)按章节进行了分割,每章一个文件,方便大家下载”,我们可以推测出这部分内容主要关注的是设计模式的基础理论及其...
《深入浅出的设计模式》是一本面向初学者的优秀教程,旨在帮助读者理解并掌握设计模式这一编程领域的核心概念。设计模式是软件工程中的宝贵经验总结,是解决常见问题的有效方法模板,它使得代码更易于理解和复用。...
这本书深入浅出地讲解了如何通过设计模式来构建可复用、可维护的面向对象系统。 首先,我们需要理解设计模式的基本概念。设计模式并不直接提供代码,而是描述在特定情境下,如何设计和实现类或对象的一种最佳实践。...
本资料“关于java深入浅出设计模式”旨在帮助读者全面理解和掌握Java中的设计模式。 一、单例模式(Singleton) 单例模式确保一个类只有一个实例,并提供一个全局访问点。在Java中,通常通过私有构造器和静态工厂...
总之,《Head First Design Patterns》是一本值得推荐的书籍,无论你是刚开始接触设计模式,还是想深入理解和应用设计模式,它都能提供宝贵的指导。通过学习这本书,你将能够更好地理解和应用设计模式,从而成为一名...
哈工大威海孙玉山老师的课程,无疑将深入浅出地讲解这些概念,帮助学生理解和掌握设计模式的精髓,提升他们的软件设计能力。课程中的实例分析和练习题将帮助学生巩固所学知识,将理论应用到实际编程中。