工厂模式,实现动态工厂列表

时间:2011-05-04 12:53:12

标签: c++ factory-pattern

我正在实现一个抽象的工厂模式(在c ++中),但是有一个小问题。

我想避免创建一个在编译时必须知道工厂存在的地方。

通常在示例中我会看到类似的内容。

Factory * getFactory()
{
    if(/*we should make factoryA*/)
    {
        return FactoryA::instance();
    }
    else if(/*we should return FactoryB*/)
    {
        return FactoryB::instance();
    }
    else
    {
        return NULL;
    }
}

我可以做这样的事,但我想要更好!

我想到的是,Factory基类会有一个工厂列表,每个继承自 Factory 的类都会创建一个静态实例,并通过受保护的类将该实例添加到列表中功能在工厂

但是,如果不使用静态对象初始化播放俄语轮盘,我无法找到一种方法。

4 个答案:

答案 0 :(得分:3)

为避免静态初始化顺序出现问题,可以使列表成为函数getFactoryList()的静态成员。这将确保当受保护的构造函数需要将工厂添加到列表时列表存在。

然后,您需要向Factory添加虚拟方法,以确定是否应使用给定的工厂。希望一次只有一家工厂有资格使用,因此工厂创建的订单不会改变返回的工厂。

答案 1 :(得分:1)

简单的事情:

class BaseFactory
{
    public:
        BaseFactory()
        {
           std::list<BaseFactory*>&  fList = getFactoryList();
           fList.push_back(this);

           // If you are feeling brave.
           // Write the destructor to remove the object from the list.
           //
           // Note C++ guarantees the list will live longer than any of the factories
           // Because the list will always be completely constructed before any
           // of the factory objects (because we get the list in the constructor).
        }

        static BaseFactory& getFactory()  // Don't return a pointer (use a reference)
        {
           std::list<BaseFactory*>&  fList = getFactoryList();
           std::list<BaseFactory*>::iterator i = selectFactory(fList);

           if (i == fList.end()
           {
               static FakeFactory  fakeFactory; // Having a fake factory that
                                                // that returns fake object
                                                // is usually a lot easier than checking for
                                                // NULL factory objects everywhere in the code
                                                //
                                                // Alternatively throw an exception.
               return fakeFactory;
           }

           return *(*i); // return reference
        }
    private:
        static std::list<BaseFactory*>& getFactoryList()
        {
            static std::list<BaseFactory*>  factoryList; // Notice the static
            return factoryList;
        }
};

答案 2 :(得分:0)

您如何从这样的设计中受益?我的意思是,即使您有该列表,您也必须根据某些标准以某种方式选择该工厂。

尝试使用Inversion Of Control模式。

如果A类需要创建一个对象,请将工厂传递给该类。

class A {
    Factory *f;
 public:
    A(Factory *f)
       : f(f)
    {  }

    void doSomething()
    {
       Object o = f->produce();
        ...
    }
}

然后您将决定在“更高级别”使用哪个工厂。工厂可能来源,形式插件等。

答案 3 :(得分:0)

我使用模式来收集子类的实例。就工厂而言,这是它的基础:

class Factory {
    public:
      virtual Foo* makeFoo()=0;
      ...
    protected:
      Factory(){
          getFactoryList().push_back(this);
      }
    private:
      FactoryList& getFactoryList();  // Returns static list
};

class FactoryA: public Factory{
      Foo* makeFoo();  // I make a Foo my way
} FACTORYINSTANCE;

您仍然需要一种在列表中搜索要使用的正确工厂的方法,并且我的宏FACTORYINSTANCE仅评估一个唯一的名称,以便调用自己的构造函数。