代码之家  ›  专栏  ›  技术社区  ›  leiz

关于工厂模式的神话[关闭]

  •  8
  • leiz  · 技术社区  · 15 年前

    这已经困扰了我一段时间,我没有线索,如果这是一个神话。

    工厂模式似乎可以减轻为类添加依赖项的痛苦。

    例如,在一本书中,它有这样的东西

    假设您有一个名为order的类。最初,它并不依赖任何东西。因此,您不必费心使用工厂来创建order对象,而只需使用plain new来实例化对象。但是,您现在有一个要求,即订单必须与客户关联创建。要添加这个额外的参数,您需要更改一百万个位置。如果你为订单类取消了一个工厂,你就可以满足新的要求,而不会有同样的痛苦。

    这与向构造函数添加额外参数有什么不同?我的意思是你仍然需要为工厂提供一个额外的理由,那也是被百万个地方使用的,对吧?

    5 回复  |  直到 10 年前
        1
  •  5
  •   foraidt    15 年前

    如果只在创建订单时知道用户,则可以实现 getCurrentUser() 工厂调用的函数。
    如果这是可能的话,工厂功能显然会获胜。如果没有,那就没有收益。

    如果,在过去,你不知道会有一个客户需要,你可能也不知道是否有可能实现 GetCurrentuser() 功能。 工厂方法的回报率可能不是很高,但并不总是等于0。

        2
  •  3
  •   Donal Fellows    15 年前

    使用工厂的真正好处是它是一个fa_ade,它隐藏了如何创建一个满足订单角色的对象。更确切地说,工厂知道你真的在做一个食品订单,没有什么可以改变,从总是做一个食品订单,有时做一个食品订单。(如果Java让你拦截 new 而创建一个子类,就不需要工厂了。但这并不“合理,公平”,所以你必须拥有它们。在这方面,允许类的子类化的对象系统更加灵活。)

        3
  •  2
  •   Community CDub    8 年前

    不,因为工厂的依赖项应该通过工厂构造函数注入,而您只在一个地方构建工厂,但是将其作为依赖项传递给需要创建订单的所有东西。从工厂获取订单的东西仍然调用相同的方法createOrder()或其他方法,因此代码没有改变。

    依赖项都应该连接在一个地方, composition root ,这应该是唯一需要更改的地方,以便向工厂添加新的依赖项。

        4
  •  1
  •   David M    15 年前

    你告诉工厂新的依赖关系,让它为你添加它。对工厂的方法调用应保持不变。

        5
  •  1
  •   Michael Aaron Safyan    10 年前

    The factory pattern 可以减轻添加依赖项的痛苦,因为 工厂可以包含州 而且,事实上,可以封装多个依赖项(例如,不提供三个依赖项,所有这些依赖项都需要调用某个对象的构造函数,而现在只提供一个工厂对象,其中工厂包含需要提供给构造函数的三个对象)。

    举个例子,比较一下:

    void DoIt(const DependencyA& a, const DependencyB& b) {
       // NOTE: "x" is a contrived additional variable that we add here to
       // justify why we didn't just pass DependencyC directly.
       int x = ComputeX(); 
       std::unique_ptr<DependencyC> dependency_c(new DependencyC(a, b, x));
       dependency_c->DoStuff();
    }
    

    还有:

    void DoIt(const DependencyCFactory& factory) {
      int x = ComputeX();
      std::unique_ptr<DependencyC> dependency_c(factory->Create(x));
      dependency_c->DoStuff();
    }
    

    注意,第二个版本需要的对方法“doit”的依赖更少。这并不意味着在整个程序中不需要这些依赖项(实际上,程序仍然在工厂的实现中使用dependencya和dependencyb)。但是,通过这样构造它,可以将依赖关系隔离为工厂代码,这样可以使其他代码更简单,从而更容易更改 DependencyC (现在只需要更新工厂本身,而不是每个实例化的地方 依赖关系 ,甚至可以获得某些安全/安保好处(例如,如果 DependencyA DependencyB 是敏感的,例如数据库密码或api密钥,将它们的使用限制在工厂,与到处传递这些信息(例如,需要使用数据库或api)的情况相比,减少了错误处理的机会。

    在书中给出的例子中,为什么 Order 有助于减少直接使用构造函数的地方;只需要修改创建工厂的一个地方来存储 Customer 作为工厂的附加字段;工厂的任何其他用途都不需要修改。相比之下,如果不使用工厂,构造函数的直接用法就会大量出现,并且必须对每个构造函数进行更新,以便以某种方式访问 顾客 对象。