Let's say I have a class like this:
class MonkeyFish { MonkeyFish( GlobalObjectA & a, GlobalObjectB & b, GlobalObjectC & c); private: GlobalObjectA & m_a; GlobalObjectB & m_b; GlobalObjectC & m_c; }
Without a factory, I need to do the following in order to instantiated a MonkeyFish
.
GlobalObjectA a; GlobalObjectB b; GlobalObjectC c; int main() { MonkeyFish * monkey_fish = new MonkeyFish(a, b, c); monkey_fish->go(); }
On the other hand, if I have a MonkeyFishFactory
, it seems like I have to do this:
GlobalObjectA a; GlobalObjectB b; GlobalObjectC c; int main() { MonkeyFishFactory mf_factory(a, b, c); MonkeyFish * monkey_fish = mf_factory.buildMonkeyFish("Bob"); monkey_fish->go(); }
I still have global objects.
Even if the MonkeyFishFactory itself created the GlobalObjects
internally (so they are now inside the MonkeyFishFactory instead of true globals), it seems like the MonkeyFishFactory itself still needs to be a global object so that I can access it anytime I want to create a MonkeyFish
.
Isn't the Factory pattern the same thing as global state in this case?
(I'm currently operating under the assumption that global state is a Bad Thing, and eliminating it is a Good Thing.)
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With