Abstract/Interface Singleton
最近一直在考虑怎么样才能将一Singleton定义为抽象的。想了很久,终于想出来了一个方案。
先说说为什么要把Singleton定义为抽象的吧,比如这里有一个类,
class IRenderSystem { public: virtual DrawPrimitives(...) = 0; };
这个IRenderSystem 是全局可访问的,而且是全局唯一的,但是它又可以有不同的实现。比如D3D9RenderSystem,D3D10RenderSystem,OGLRenderSystem等等。
所以我想用一个抽象的Singleton来定义一个全局的可访问接口。我把它叫做Abstract Singleton或Interface Singleton。
目前我的实现方法是配合Abstract Factory来完成。大致思路程如下
template<typename T> class AbstractSingleton { public: static T* GetSingletonPtr() { return msSingleton; } static T& GetSingleton() { assert(); return *msSingleton; } static void CreateSingleton() { if( msSingleton != NULL ) msSingleton = msSingletonCreator->createInstance(); } static void DestroySingleton() { if( msSingleton != NULL ) { msSingletonCreator->destroyInstance(msSingleton); msSingleton = NULL; } } static void SwitchSingleton(AbstractCreator<T>* creator) { msSingletonCreator = creator; } };这里的AbstractCreator<T>实质上类似一个抽象工厂,只不过与工厂不同的是它不再是一个“工厂”,因为它不需要批量创建对象,我把它叫做Abstract Singleton Creator.
当然如果不使用这种方法,也能达到同样的目的,比如使用一个真正的Singleton,来实现一个管理器,比如一个Root,它可能定义一个方法IRenderSystem* GetRenderSystem();
这样得到的其实也是一个全局唯且可见的实例。不过个人觉得这种做法灵活性和复用性不高。
这里的使用个人感觉更爽点,IRenderSystem::GetSingleton() 就可以了。