假设我有这样一个类:
class MonkeyFish { MonkeyFish( GlobalObjectA & a, GlobalObjectB & b, GlobalObjectC & c); private: GlobalObjectA & m_a; GlobalObjectB & m_b; GlobalObjectC & m_c; }
没有工厂,我需要执行以下操作才能实例化a MonkeyFish
.
GlobalObjectA a; GlobalObjectB b; GlobalObjectC c; int main() { MonkeyFish * monkey_fish = new MonkeyFish(a, b, c); monkey_fish->go(); }
另一方面,如果我有MonkeyFishFactory
,似乎我必须这样做:
GlobalObjectA a; GlobalObjectB b; GlobalObjectC c; int main() { MonkeyFishFactory mf_factory(a, b, c); MonkeyFish * monkey_fish = mf_factory.buildMonkeyFish("Bob"); monkey_fish->go(); }
我还有全局对象.
即使MonkeyFishFactory本身在GlobalObjects
内部创建(因此它们现在在MonkeyFishFactory而不是真正的全局内),似乎MonkeyFishFactory 本身仍然需要是一个全局对象,以便我可以随时访问它来创建一个MonkeyFish
.
在这种情况下,工厂模式与全局状态不一样吗?
(我目前的运作假设全球状态是坏事,消除它是一件好事.)
你在这里混淆概念吗?
当您返回隐藏在抽象接口后面的具体类的实例时,通常会应用Factory模式.这个想法是调用者只看到界面,甚至不知道对象的具体类型是什么.所有这些都是关于基于参数创建对象实例并解耦与从创建对象的用户决定创建什么对象相关联的逻辑.
你所描述的是Singleton(或MonoState)和Factory的混合体.你的工厂有状态所以不能静止.在这种情况下,您需要应用类似Singleton模式的东西来控制单个Factory实例的创建,并在其中隐藏适当的全局变量:
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();
该Singleton
模式控制工厂实例的创建.该Factory
模式隐藏了围绕创建实现IMonkeyFish
接口的对象的细节.Good Thing(TM)隐藏了全局状态,并将MonkeyFish
具体细节与创建实例分离.
然而,使用这些Singleton
东西的使用或正确性是另一个问题.关于这一点,可能还有很多线程浮出水面.
全球国家本身并不是坏事. 公共全球状态是一件坏事.Factory模式有助于封装全局状态,这是一件好事.
工厂里没有全球状态.它只是创建对象.既然它在工厂里没有任何状态.全球化是可以的.