说到Singleton,׃能不提全局变量。过L们反对全局变量Qؓ什么呢Q全局变量一般存在三个问题:
<!--[if !supportLists]-->1. 命名冲突Q也叫名字污?/span><!--[endif]-->
<!--[if !supportLists]-->2. 初始化顺序依赖问题?/span><!--[endif]-->
<!--[if !supportLists]-->3. q程代码耦合问题?/span><!--[endif]-->
对于W一个问题,其实解决很简单,通过命名规范可以有效解决。另外,借助语言机制也容易解冻I例如C++?/span>namespace, class?/span>struct的静态数据成员?/span>Java?/span>C#Ҏ不允许全局变量Qƈ且引入包机制Q都可以~解甚至消除q一影响Q至,Singleton对该问题的解军_度ƈ不超q这些语a提供的内建机制?/span>
初始化顺序依赖问题是一个相当微妙的问题。借助?/span>Singleton, 我们可以强制某些对象按需创徏Q避免初始化序依赖D的问题。然而,初始化顺序是一个雷区,我们必须心翼地绕q去Q但首先不应该通过实现技术来规避问题Q而应该调整设计,让初始化序问题Ҏ不出现才是上{。第二,某些情况下,我们实需要规避初始化序问题Q我们也需要清醒地认识到该实现手段影响到的代码范围Q受其媄响的部分单一好?/span>
q程代码耦合Q这是我们反对全局变量的核心问题。Q何长距离的耦合都将D代码的可L下降,q而可能媄响代码结构,Dl构僵化Q无力应对因需求变化导致的l构调整。很遗憾Q?/span>Singletonq不能对q个问题有Q何帮助。当我们回避全局变量的时候,事实上,我们也规避了上述的三个问题。可是,如果我们不能审慎C?/span>Singleton׃重新落入全局变量的核心陷׃厅R?/span>
名称 | Singleton |
l构 |
![]() |
意图 | 保证一个类仅有一个实例,q提供一个访问它的全局讉K炏V?/font> |
适用?/font> |
|
在很多操作中Q比如徏立目?数据库连接都需要这L单线E操作?/p>
q有, singleton能够被状态化; q样Q多个单态类在一起就可以作ؓ一个状态仓库一样向外提供服务,比如Q你要论坛中的帖子计数器Q每ơ浏览一ơ需要计敎ͼ单态类能否保持住这个计敎ͼq且能synchronize的安全自动加1Q如果你要把q个数字怹保存到数据库Q你可以在不修改单态接口的情况下方便的做到?/p>
另外斚wQSingleton也能够被无状态化。提供工h质的功能,
Singleton模式׃ؓ我们提供了这样实现的可能。用Singleton的好处还在于可以节省内存Q因为它限制了实例的个数Q有利于Java垃圾回收Qgarbage collectionQ?br />
我们常常看到工厂模式中类装入?class loader)中也用Singleton模式实现?因ؓ被装入的cd际也属于资源?br />
如何使用?
一般Singleton模式通常有几UŞ?
public class Singleton { private Singleton(){} //在自己内部定义自׃个实例,是不是很奇怪? private static Singleton instance = new Singleton(); //q里提供了一个供外部讉K本class的静态方法,可以直接讉K
|
W二UŞ?
public class Singleton {
private static Singleton instance = null; }
|
使用Singleton.getInstance()可以讉K单态类?/p>
上面W二中Ş式是lazy initializationQ也是说第一ơ调用时初始SingletonQ以后就不用再生成了?/p>
注意到lazy initialization形式中的synchronizedQ这个synchronized很重要,如果没有synchronizedQ那么用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴者进一步研I?/p>
一般认为第一UŞ式要更加安全些?br />