Object Factories.
抽象工厂, 基于多态的实现, 面向接口的设计, 为了避免在实现中对具体的派生类的引用。通常使用Object Factories来生成具体对象。
通常的最简单实现方法是, 给Factory传入一个identifyId, 根据id, factory生成一个具体的对象, 返回基类接口。 但是这样的做法, 工厂还是对具体类有依赖, 而且每次加一个新的对象, 都要修改数个文件, 有较强的耦合性。
用来处理这个问题的办法是: 让工厂维护一个由函数指针构成的集合, 不同的指针生成不同的对象, 需要加入对象的类,只需要在工厂注册自己的id和方法即可。
有了解决方案, 接下来就是泛化这个解决方案了, 思路完全相同, 只是加了几个template参数。 实现如下:
template
<
class AbstractProduct,
typename IdentifierType,
typename ProductCreator = AbstractProduct* (*)(),
template<typename, class>
class FactoryErrorPolicy = DefaultFactoryError
>
class Factory
: public FactoryErrorPolicy<IdentifierType, AbstractProduct>
{
public:
bool Register(const IdentifierType& id, ProductCreator creator)
{
return associations_.insert(
typename IdToProductMap::value_type(id, creator)).second;
}
bool Unregister(const IdentifierType& id)
{
return associations_.erase(id) == 1;
}
AbstractProduct* CreateObject(const IdentifierType& id)
{
typename IdToProductMap::iterator i = associations_.find(id);
if (i != associations_.end())
{
return (i->second)();
}
return this->OnUnknownType(id);
}
private:
typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
IdToProductMap associations_;
};
最后还介绍了一个CloneFactory, 和ObjectFactory很类似, 区别在于CloneFactory依赖typeInfo来找寻Clone函数, 同时函数指针的类型也不同,需要传入一个AbstractProduct对象。 其他基本雷同。如下:
template
<
class AbstractProduct,
class ProductCreator =
AbstractProduct* (*)(const AbstractProduct*),
template<typename, class>
class FactoryErrorPolicy = DefaultFactoryError
>
class CloneFactory
: public FactoryErrorPolicy<TypeInfo, AbstractProduct>
{
public:
bool Register(const TypeInfo& ti, ProductCreator creator)
{
return associations_.insert(
typename IdToProductMap::value_type(ti, creator)).second;
}
bool Unregister(const TypeInfo& id)
{
return associations_.erase(id) == 1;
}
AbstractProduct* CreateObject(const AbstractProduct* model)
{
if (model == 0) return 0;
typename IdToProductMap::iterator i =
associations_.find(typeid(*model));
if (i != associations_.end())
{
return (i->second)(model);
}
return this->OnUnknownType(typeid(*model));
}
private:
typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
IdToProductMap associations_;
};
当然, Factory一般都是Singleton对象, 可以用前几章介绍的SingletonHolder包装, 一切ok. 省了大量代码, 耦合性也小。
这章重点在于ObjectFactory的概念, 以及如何分离ObjectFactory的需求, 以便将其泛化, 泛化的过程自然解耦。 至于泛化的实现, 相比于泛化的过程, 到显得简单了许多。