Global state is not in-and-of-itself a Bad Thing. Public global state is a Bad Thing. The Factory pattern helps encapsulate global state, which is a Good Thing.
There are no global state in the Factory. It just creates objects. Since it not any state in the factory. It's OK to be global.
You don't have to leave global objects. Monkey fish factory should create those GlobalOjectA|B|C on demand. Using switch or if inside method to determine which one.
A factory class can be static. A Sara said it has no state so it is OK to do this.
You have encapsulated control over creation of objects in a factory. You want your instantiation details to be hidden away, not reproduced everywhere you need a new MonkeyFish. Think about testing, Single Responsibility, and the Law of Demeter. Why should your class that wants to use a MonkeyFish need to know anything about the work it takes to build one. What if you want to test MonkeyFish? How would you do it if you didn't have creation details encapsulated?
I think you are thinking of the Singleton Pattern, not the Factory Pattern. In the singleton pattern you only have on instance of a class which basically makes it the equivalent of a global object except there is no global variable attached to it.
Are you confusing concepts here?
The Factory pattern is usually applied when you are returning an instance of a concrete class that hides behind an abstract interface. The idea is that the caller will see just the interface and doesn't even have to know what the concrete type of the object is. It is all about creating an object instance based on parameters and decoupling the logic associated with deciding what object to create from the user creating the object.
What you are describing is a mixture of Singleton (or MonoState) and Factory. Your Factory has state so it cannot be made static. In this case, you will need to apply something like the Singleton pattern to control the creation of a single Factory instance with the appropriate globals hidden within it:
class IMonkeyFish {
public:
virtual ~IMonkeyFish() = 0;
virtual void go() = 0;
};
class Factory {
public:
static Factory& instance();
IMonkeyFish* createMonkeyFish();
protected:
Factory(GlobalObjectA& a, GlobalObjectB& b, GlobalObjectC& c);
private:
static Factory *theInstance;
GlobalObjectA& instanceOfA;
GlobalObjectB& instanceOfB;
GlobalObjectC& instanceOfC;
};
Factory& factory = Factory::instance();
IMonkeyFish* fishie = factory.createMonkeyFish();
fishie->go();
The Singleton
pattern governs the creation of the factory instance. The Factory
pattern hides the details surrounding the creation of objects that implement the IMonkeyFish
interface. The Good Thing (TM) is the hiding of the global state and decoupling of the MonkeyFish
concrete details from creating an instance.
The usage or correctness of using the Singleton
stuff is a whole other issue though. There are probably a bunch of threads floating around about that as well.
The job of a factory class is to instantiate an object and pass it back to the caller; not to pick which global instantiated object to use. So, your factory example is incorrect. It should be:
int main()
{
MonkeyFish * monkey_fish = MonkeyFishFactory::buildMonkeyFish("Bob");
monkey_fish->go();
}
Notice, no global objects, and MonkeyFishFactory is not instantiated.
You should state your constraints and requirements if you want to get a good answer. The most important thing to get a good answer is knowing what question to ask.
In the code snippets you provided you have decided to use globals, but that has nothing to do with whether you use a Factory or not. If you use a factory that still depends on those globals, then you just have another piece of code to pile up with the rest.
Try to state clearly what you are trying to achieve and you will probably get a better answer.