C++ Isn';工厂模式不是和全局状态一样吗?

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

假设我有一门课是这样的:

class MonkeyFish { MonkeyFish( GlobalObjectA & a, GlobalObjectB & b, GlobalObjectC & c); private: GlobalObjectA & m_a; GlobalObjectB & m_b; GlobalObjectC & m_c; } 另一方面,如果我有一个
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”); 猴子鱼->走(); }
  • 我仍然有全局对象

  • 即使MonkeyFishFactory本身在内部创建了
    GlobalObject
    (因此它们现在在MonkeyFishFactory中而不是真正的全局对象),MonkeyFishFactory本身似乎仍然需要是一个全局对象,以便我可以在任何时候创建
    MonkeyFish
    来访问它

  • GlobalObjectA a; GlobalObjectB b; GlobalObjectC c; int main() { MonkeyFish * monkey_fish = new MonkeyFish(a, b, c); monkey_fish->go(); } 在这种情况下,工厂模式与全局状态不是一回事吗


    (我目前的工作假设是,全局状态是一件坏事,消除它是一件好事。)

    全局状态本身并不是一件坏事公共全球国家是一件坏事。工厂模式有助于封装全局状态,这是一件好事。

    工厂中没有全局状态。它只是创建对象。
    因为它在工厂里没有任何状态。作为全局对象是可以的。

    您不必离开全局对象。猴子鱼工厂应该根据需要生产这些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的答案。