最近一直在考虑怎么样才能将一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() 就可以了。