所有工厂方法都不能是静态的吗?产生产品的东西需要状态吗?何时适合实例工厂或静态工厂方法?你能举例说明两者的区别吗?
答案 0 :(得分:28)
假设通过“实例工厂方法”你实际上是在谈论GoF“工厂方法”,Joshua Bloch在他的书“Effective Java”中描述了术语“静态工厂方法”。谷歌搜索我到达这些网站:
希望它有助于使差异更加清晰。
遵循Marvo的建议:
定义用于创建对象的接口,但让子类决定实例化哪个类。 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(); }
}
类可以提供公共静态工厂方法,它只是一个返回类实例的静态方法。 (...)静态工厂方法的一个优点是,与构造函数不同,它们具有名称。 (...)静态工厂方法的第二个优点是,与构造函数不同,它们不需要在每次调用时创建新对象。 (...)静态工厂方法的第三个优点是,与构造函数不同,它们可以返回其返回类型的任何子类型的对象。 (...)仅提供静态工厂方法的主要缺点是没有公共或受保护构造函数的类不能被子类化。
示例(Java代码):
public class Boolean {
...
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
...
}
答案 1 :(得分:6)
我目前的偏好是为了更容易测试,使工厂方法不是静态的。您无法在运行时更改静态工厂方法调用,而如果我可以为对象提供工厂实现,那么我可以更彻底地测试它,因为我可以更好地控制上下文和对象图。
答案 2 :(得分:2)
如果您从工厂返回Singleton,那么您将需要确保只有一个实例,如果您要在每次调用工厂时创建一个新实例,然后将其设置为静态。
答案 3 :(得分:1)
这取决于,例如,您可以拥有一个只生产一定数量对象的工厂,在这种情况下会有一个关联状态。在大多数情况下,工厂方法可以是静态的,只要它们不依赖于任何非静态变量(例如非静态全局变量等)来创建它们。它还倾向于区分不同工厂的不同部分应用程序,因此根据工厂中是否存在状态,您可能会认为所有工厂方法都应该是静态的,请检查哪种情况适用于你并适当地写下来。
另一个考虑因素是static关键字,这会导致静态内容只在内存中实例化一次,但缺点是它始终驻留在进程内存中(这会增加工作集大小)。这可能是你不想要的东西,因为你的工厂在某些区域可能具有非常高的位置,否则它只会在其他地方使用内存,但这通常是一个优化问题,只有在内存问题时才应该查看你的申请中会产生压力。
答案 4 :(得分:0)
如果以前需要实例,则可以使用静态工厂,否则可以实例化工厂本身并将其传递给代码。