I've been reading and searching the web for a while now but haven't found a nice solution. Here's what I want to do:
I am writing a library that defines an abstract base class - lets call it IFoo.
class IFoo {
public:
virtual void doSomething() = 0;
virtual ~IFoo() {}
};
The library also defines a couple of implementations for that - lets call them FooLibOne and FooLibTwo.
In order to encapsulate the creation process and decide which concrete implementation is used depending on some runtime paramter, I use a factory FooFactory that maps std::string to factory methods (in my case boost::function, but that should not be the point here). It also allows new factory methods to be registered. It looks something like this:
class FooFactory {
public:
typedef boost::function<IFoo* ()> CreatorFunction;
IFoo* create(std::string name);
void registerCreator(std::string name, CreatorFunction f);
private:
std::map<std::string, CreatorFunction> mapping_;
};
For now, I added the implementations provided (FooLibOne, FooLibTwo) by the library directly in the constructor of FooFactory - thus they are always available. Some of the library code uses the FooFactory to initialize certain objects etc. I have refrained from using the Singleton pattern for the factories so far since tee pattern is debated often enough and I wasn't sure, how different implementations of the Singleton pattern would work in combination with possibly multiple shared libraries etc.
However, passing around the factories can be a little cumbersome and I still think, this is one of the occassions the Singleton pattern could be of good use. Especially if I consider, that the users of the library should be able to add more implementations of IFoo which should also be accessible for the (already existing) library code. Of course, Dependency Injection - meaning I pass an instance of a factory through the constructor - could do the trick (and does it for now). But this approach kind of fails if I want to be even more flexible and introduce a second layer of dynamic object creation. Meaning: I want to dynamicly create objects (see above) within dynamically created objects (say implementations of an abstract base class IBar - BarOne and BarTwo - again via a factory BarFactory).
Lets say BarOne requires an IFoo object but BarTwo doesn't. I still have to provide the FooFactory to the BarFactory in any case, since one of the IBar implementations might need it. Having globally accessible factories would mitigate this problem and I wouldn't be forced to forsee, which factories may be needed by implementations of a specific interface. In addition I could register the creation methods directly in the source file of the implementations.
FooFactory::Instance().registerCreator("new_creator", boost::bind(...));
Since I think it is a good idea, what would be the right way to implement it? I was going for a templated approach like the SingletonHolder from Modern C++ Design (see also Loki library) to wrap the factories. However, I'd rather implement it as a Meyer's Singleton instead. But I still think there will be issues with shared libraries. The solution should work with GCC (and preferably MSVC). I'm also open for other ideas from a design point of view but please avoid the common "Singletons are evil"-rants. ;-)
Thanks in advance.