Singleton可能是Gof设计模式中最简单同时也应用最广的模式了,各种实现也非常之多。
原本对此也没什么想法,然而,直到看到了Ogre中Singleton的实现,才忽然茅塞顿开,明白了Singleton究竟是怎么回事:
与网上各种复杂的实现相比较,这个实现看似简陋,但是,让我们先来看看Gof中Singleton模式的目标是什么吧:
Ensure a class only has one instance, and provide a global point of access to it.
确保某个类只有一个实例,并且提供这个实例的全局访问点。
Ogre的这个实现很好的完成了这两点。而其他常见的实现(包括《设计模式》中Gof给出的实现),多数除了这两点外,还做了另外一件事情,就是在第一次访问时创建这个类的唯一实例。
事实上,关于Singleton模式,说得最多的或许就是如何在第一次访问时创建这个实例了。毕竟Singleton本身其实很简单,而对于多线程的程序,如何确定这个“第一次”还真是个问题。其实这已经是另一个问题,即对象的晚绑定,如何在真正需要一个对象时才创建它。《More Effective C++》中对此有专门的论述。
那么在Singleton中,真的需要对象的晚绑定吗?
我在工作中也碰到过不少用Singleton的地方,然而几乎每一个Singleton的类,都提供了类似Init的函数(有些Init方法还会有参数),用于在程序刚开始,线程还没有创建的时候初始化Singleton对象。而那些没有初始化函数的,也往往会在程序开始时访问一下,把对象先创建出来。
对象的晚绑定,只有在一个对象其实并不会被真正使用到的情况下,才能发挥最大的效用。反观Singleton模式,它的目标就是提供给所有人使用,因此往往会被大量使用。那么又有多大的概率,设计出一个实际不会被用到的Singleton呢?即使确有必要,也可以把晚绑定和Singleton分开实现。
既如此,就没有必要在Singleton中加入创建对象的代码。于是,我们就得到了类似Ogre中那样简单的Singleton。虽然简单,功能已足够,而且不容易出错。
应用示例: