C++ Isn';工厂模式不是和全局状态一样吗?
假设我有一门课是这样的: class MonkeyFish { MonkeyFish( GlobalObjectA & a, GlobalObjectB & b, GlobalObjectC & c); private: GlobalObjectA & m_a; GlobalObjectB & m_b; GlobalObjectC & m_c; } 另一方面,如果我有一个C++ Isn';工厂模式不是和全局状态一样吗?,c++,global-variables,factory,global,C++,Global Variables,Factory,Global,假设我有一门课是这样的: class MonkeyFish { MonkeyFish( GlobalObjectA & a, GlobalObjectB & b, GlobalObjectC & c); private: GlobalObjectA & m_a; GlobalObjectB & m_b; GlobalObjectC & m_c; } 另一方面,如果我有一个MonkeyFishFactory,我似乎必须这样做: GlobalObjectA
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();
}
球形物体;
全球目标b;
全球目标c;
int main()
{
MonkeyFishFactory mf_工厂(a、b、c);
MonkeyFish*monkey_fish=mf_工厂。构建MonkeyFish(“Bob”);
猴子鱼->走();
}
GlobalObject
(因此它们现在在MonkeyFishFactory中而不是真正的全局对象),MonkeyFishFactory本身似乎仍然需要是一个全局对象,以便我可以在任何时候创建MonkeyFish
来访问它(我目前的工作假设是,全局状态是一件坏事,消除它是一件好事。)全局状态本身并不是一件坏事公共全球国家是一件坏事。工厂模式有助于封装全局状态,这是一件好事。工厂中没有全局状态。它只是创建对象。
因为它在工厂里没有任何状态。作为全局对象是可以的。您不必离开全局对象。猴子鱼工厂应该根据需要生产这些GlobalOjectA | B | C。使用switch或if-inside方法来确定哪一个。您已经封装了对工厂中对象创建的控制。您希望将实例化细节隐藏起来,而不是在需要新MonkeyFish的地方复制。想想测试、单一责任和德米特定律。为什么想要使用MonkeyFish的类需要了解构建MonkeyFish所需的工作。如果你想测试猴子鱼呢?如果没有封装创建细节,您会怎么做?我认为您考虑的是单例模式,而不是工厂模式。在单例模式中,你只有一个类的实例,这个类基本上等同于一个全局对象,只是没有附加任何全局变量。你在这里混淆了概念吗 工厂模式通常在返回隐藏在抽象接口后面的具体类的实例时应用。其思想是调用方只看到接口,甚至不必知道对象的具体类型。这一切都是关于基于参数创建对象实例,并将与决定要创建的对象相关的逻辑与创建对象的用户分离 您所描述的是单态(或单态)和工厂的混合。您的工厂有状态,因此不能使其处于静态。在这种情况下,您需要应用类似于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
接口的对象的细节。好东西(TM)是隐藏全局状态,并将MonkeyFish
具体细节与创建实例分离
但是,使用
单例的用法或正确性是另一个问题。工厂类的任务是实例化一个对象并将其传递回调用方;不选择要使用的全局实例化对象。因此,您的工厂示例是不正确的。应该是:
int main()
{
MonkeyFish * monkey_fish = MonkeyFishFactory::buildMonkeyFish("Bob");
monkey_fish->go();
}
注意,没有全局对象,MonkeyFishFactory也没有实例化。如果您想得到一个好的答案,您应该说明您的约束和要求。要得到一个好的答案,最重要的是知道该问什么问题
在您提供的代码片段中,您已经决定使用globals,但这与是否使用工厂无关。如果您使用的工厂仍然依赖于这些全局变量,那么您就有另一段代码要与其他代码一起堆积
尽量清楚地说明您想要实现的目标,您可能会得到更好的答案。如果对象是数据库连接之类的东西,那么--在创建每个MonkeyFish时创建多个数据库连接真的是个好主意吗?在db连接的情况下,您最好创建一个池。在这种情况下,我说的是工厂。我会使用工厂来创建多个MonkeyFish对象,而不仅仅是一个。@Runcible:不,你说的是同时使用工厂和Singleton。你所看到的问题是单例对象,正如你所描述的,基本上只是一个精心打扮的全局状态。正如j_所说,你的工厂对象是一个单例对象。一个静态对象可以是一个有状态的对象。这只是全局状态。您是否打算将buildMonkeyFish()作为MonkeyFishFactory类的静态方法?然后在C++中,你会调用它为“MyKiKiFix::BuffdMnKiFISH(鲍伯)”;谢谢我做过任何C++代码都太长了,你在讨论使用工厂和单用。你所感觉到的问题是关于单身的,正如你所描述的,基本上只是一个打扮得很好的全球状态。见D.Shawley的答案。