实例工厂方法Vs静态工厂方法

use*_*434 41 java factory-pattern

不是所有的工厂方法都是静态的吗?产生产品的东西需要状态吗?何时适合实例工厂或静态工厂方法?你能举例说明两者的区别吗?

Ram*_*ara 31

假设通过"实例工厂方法"你实际上是在谈论GoF"工厂方法",Joshua Bloch在他的书"Effective Java"中描述了术语"静态工厂方法".谷歌搜索我到达这些网站:

希望它有助于使差异更加清晰.

遵循Marvo的建议:

  • GoF中所述的工厂方法:

    定义用于创建对象的接口,但让子类决定实例化哪个类.Factory Method允许类将实例化延迟到子类.

示例(Java代码):

    public abstract class Product { ... }

    public class ConcreteProduct extends Product { ... }

    public abstract class Creator {
      public void anOperation() { ... product = factoryMethod(); ... }
      public abstract Product factoryMethod();
    }

    public class ConcreteCreator extends Creator {
      public Product factoryMethod() { return new ConcreteProduct(); }
    }
Run Code Online (Sandbox Code Playgroud)
  • 有效Java中所述的静态工厂方法:

    类可以提供公共静态工厂方法,它只是一个返回类实例的静态方法.(...)静态工厂方法的一个优点是,与构造函数不同,它们具有名称.(...)静态工厂方法的第二个优点是,与构造函数不同,它们不需要在每次调用时创建新对象.(...)静态工厂方法的第三个优点是,与构造函数不同,它们可以返回其返回类型的任何子类型的对象.(...)仅提供静态工厂方法的主要缺点是没有公共或受保护构造函数的类不能被子类化.

示例(Java代码):

    public class Boolean {
      ...
      public static Boolean valueOf(boolean b) {
        return b ? Boolean.TRUE : Boolean.FALSE;
      }
      ...
    }
Run Code Online (Sandbox Code Playgroud)


Nat*_* W. 7

我目前的偏好是为了更容易测试,使工厂方法不是静态的.您无法在运行时更改静态工厂方法调用,而如果我可以为对象提供工厂实现,那么我可以更彻底地测试它,因为我可以更好地控制上下文和对象图.

  • 我不明白你在说什么.你能举个例子说明你的观点吗? (4认同)
  • 什么@NateW。意思是,如果我有一个调用静态工厂方法的方法,我与该静态工厂方法的返回紧密耦合。如果我使用非静态工厂,我可以在测试期间传入一个模拟工厂以返回一个模拟对象。``` 工厂 factory = Mockito.mock(Factory.class); 混凝土混凝土 = Mockito.mock(Concrete.class); 当(工厂。创建())。然后返回(具体);ClassToTest.methodToTest(工厂); // 使用工厂创建 Concrete 的实例 ``` (2认同)

Jes*_*mos 1

这取决于,例如,您可以有一个工厂,它只会生产一定数量的对象,在这种情况下,将会有一个关联的状态。大多数情况下,工厂方法可以是静态的,只要它们不依赖于任何非静态变量(例如非静态全局变量等)来创建。它还倾向于针对应用程序的不同部分区分不同的工厂,因此取决于您的工厂中是否有状态,您会选择什么,所有工厂方法都应该是静态的,这并不是一成不变的,请检查适用于什么情况你并适当地写下来。

另一个考虑因素是 static 关键字,这会导致静态的内容仅在内存中实例化一次,但缺点是它始终驻留在进程内存中(这会增加工作集大小)。这可能是您不希望发生的事情,因为您的工厂在某些区域可能具有非常高的局部性,否则它只会在其他地方耗尽内存,但这通常是一个优化问题,只有在内存问题时才应该考虑您的申请中会出现压力。