Modern c++ design 第8章

    技术2022-05-11  171

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


    最新回复(0)