什么时候在对象中使用工厂方法而不是factory类是一个好主意?
当前回答
当您需要几个具有相同参数类型但具有不同行为的“构造函数”时,它们也很有用。
其他回答
假设你有不同的客户,他们有不同的偏好。有人需要大众、奥迪等等。有一样东西是共同的,那就是汽车。
为了让我们的客户满意,我们需要一个工厂。工厂只需要知道客户想要哪一辆车,并将其交付给客户。如果以后我们有另一辆车,我们可以很容易地扩大我们的停车场和工厂。
下面你可以看到一个例子(ABAP):
现在,我们将创建工厂的实例,并监听客户的愿望。
我们只用一个create()方法创建了三种不同的汽车。
结果:
如果你想让逻辑更清晰,程序更可扩展,工厂模式通常非常有用。
在对象中使用工厂方法是个好主意:
对象的类不知道它必须创建什么确切的子类 Object的类被设计成它创建的对象由子类指定 对象的类将其职责委托给辅助子类,并且不知道确切的类将承担这些职责
在以下情况下使用抽象工厂类是个好主意:
对象不应该依赖于其内部对象是如何创建和设计的 一组链接的对象应该一起使用,您需要满足这个约束 对象应该由几个可能的链接对象家族中的一个来配置,这些对象将成为父对象的一部分 它需要共享只显示接口而不显示实现的子对象
这真的是个品味问题。工厂类可以根据需要进行抽象/接口,而工厂方法是轻量级的(而且往往是可测试的,因为它们没有定义的类型,但它们需要一个众所周知的注册点,类似于服务定位器,但用于定位工厂方法)。
考虑一个场景,当您必须设计Order和Customer类时。为了简单和初始需求,您不需要Order类的factory,并使用许多“new Order()”语句填充应用程序。一切都很顺利。
现在出现了一个新的需求,即Order对象不能在没有客户关联的情况下实例化(新的依赖项)。现在你有以下考虑。
1-你创建了只对新实现有效的构造函数重载。(不可接受)。 2-您更改Order()签名并更改每个调用。(这不是一个很好的练习,而且真的很痛苦)。
相反,如果你已经为Order Class创建了一个工厂,你只需要修改一行代码就可以了。我建议几乎所有聚合关联都使用Factory类。希望这能有所帮助。
如果你想在使用方面创建一个不同的对象。它很有用。
public class factoryMethodPattern {
static String planName = "COMMERCIALPLAN";
static int units = 3;
public static void main(String args[]) {
GetPlanFactory planFactory = new GetPlanFactory();
Plan p = planFactory.getPlan(planName);
System.out.print("Bill amount for " + planName + " of " + units
+ " units is: ");
p.getRate();
p.calculateBill(units);
}
}
abstract class Plan {
protected double rate;
abstract void getRate();
public void calculateBill(int units) {
System.out.println(units * rate);
}
}
class DomesticPlan extends Plan {
// @override
public void getRate() {
rate = 3.50;
}
}
class CommercialPlan extends Plan {
// @override
public void getRate() {
rate = 7.50;
}
}
class InstitutionalPlan extends Plan {
// @override
public void getRate() {
rate = 5.50;
}
}
class GetPlanFactory {
// use getPlan method to get object of type Plan
public Plan getPlan(String planType) {
if (planType == null) {
return null;
}
if (planType.equalsIgnoreCase("DOMESTICPLAN")) {
return new DomesticPlan();
} else if (planType.equalsIgnoreCase("COMMERCIALPLAN")) {
return new CommercialPlan();
} else if (planType.equalsIgnoreCase("INSTITUTIONALPLAN")) {
return new InstitutionalPlan();
}
return null;
}
}