Search code examples
c++factory-pattern

Factory pattern, implementing a dynamic list of factories


I'm implementing an abstract factory pattern (in c++), but there is a slight problem.

I'd like to avoid creating a place which must know at compile time what factories exist.

Usually in the examples I see something like this.

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

I could do something like this, but I want better!

What I have in mind is that the Factory base class would have a list of Factories, each class inherited from Factory would create a static instance and add that instance to the list, through a protected class function in Factory.

However, I can't figure out a way to do this without playing Russian Roulette with static object initialization.


Solution

  • Somthing Simple:

    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;
            }
    };