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的需求, 以便将其泛化, 泛化的过程自然解耦。 至于泛化的实现, 相比于泛化的过程, 到显得简单了许多。
