什么时候在对象中使用工厂方法而不是factory类是一个好主意?
当前回答
假设你有不同的客户,他们有不同的偏好。有人需要大众、奥迪等等。有一样东西是共同的,那就是汽车。
为了让我们的客户满意,我们需要一个工厂。工厂只需要知道客户想要哪一辆车,并将其交付给客户。如果以后我们有另一辆车,我们可以很容易地扩大我们的停车场和工厂。
下面你可以看到一个例子(ABAP):
现在,我们将创建工厂的实例,并监听客户的愿望。
我们只用一个create()方法创建了三种不同的汽车。
结果:
如果你想让逻辑更清晰,程序更可扩展,工厂模式通常非常有用。
其他回答
这真的是个品味问题。工厂类可以根据需要进行抽象/接口,而工厂方法是轻量级的(而且往往是可测试的,因为它们没有定义的类型,但它们需要一个众所周知的注册点,类似于服务定位器,但用于定位工厂方法)。
任何将对象创建延迟到其需要使用的对象的子类的类都可以视为Factory模式的示例。
我在https://stackoverflow.com/a/49110001/504133的另一个回答中详细提到过
当它们返回的对象类型具有私有构造函数时,当不同的工厂类在返回的对象上设置不同的属性时,或者当特定的工厂类型与其返回的具体类型耦合时,工厂类非常有用。
WCF使用ServiceHostFactory类来检索不同情况下的ServiceHost对象。IIS使用标准的ServiceHostFactory来检索.svc文件的ServiceHost实例,但是WebScriptServiceHostFactory用于向JavaScript客户端返回序列化的服务。ADO。NET Data Services有自己特殊的DataServiceHostFactory和ASP。NET有它的ApplicationServicesHostFactory,因为它的服务有私有构造函数。
如果只有一个类在使用工厂,那么可以在该类中使用工厂方法。
GOF定义:
定义一个用于创建对象的接口,但是让子类来决定实例化哪个类。工厂方法允许类延迟实例化到子类。
一般例子:
public abstract class Factory<T> {
public abstract T instantiate(Supplier<? extends T> supplier);
}
具体类
public class SupplierFactory<T> extends Factory<T> {
@Override
public T instantiate(Supplier<? extends T> supplier) {
return supplier.get();
}
}
实现
public class Alpha implements BaseInterface {
@Override
public void doAction() {
System.out.println("The Alpha executed");
}
}
public class Beta implements BaseInterface {
@Override
public void doAction() {
System.out.println("The Beta executed");
}
}
public interface BaseInterface {
void doAction();
}
public class Main {
public static void main(String[] args) {
Factory<BaseInterface> secondFactory = new SupplierFactory<>();
secondFactory.instantiate(Beta::new).doAction();
secondFactory.instantiate(Alpha::new).doAction();
}
}
短暂的优势
您正在分离可以变化的代码和不变的代码(即,使用简单工厂模式的优点仍然存在)。这种技术可以帮助您轻松地维护代码。 你的代码不是紧密耦合的;因此,你可以随时在系统中添加新的类,如Lion、Beer等,而无需修改现有的体系结构。因此,您遵循了“修改封闭,扩展开放”的原则。
工厂方法应该被认为是构造函数的替代品——尤其是在构造函数表达能力不够的时候。
class Foo{
public Foo(bool withBar);
}
表现力不如:
class Foo{
public static Foo withBar();
public static Foo withoutBar();
}
当你需要一个复杂的过程来构造对象时,当构造需要一个你不想要的实际类的依赖关系时,当你需要构造不同的对象时,工厂类是有用的。