问题描述
我试图理解抽象工厂模式,但它真的很难。我在 Head First Design Patterns 书中看到了以下示例,试图描述依赖关系以及为什么依赖是不好的。但是,我不明白该代码示例的以下说法。
因为比萨饼具体实现的任何变化都会影响
DependentPizzaStore
,我们说 DependentPizzaStore
“取决于”披萨
实现。
我真的不明白它如何影响仅由 new
启动并使用 bake
、cut
等方法的类。 DependentPizzaStore
对具体实现一无所知。
public class DependentPizzaStore {
public Pizza createPizza(String style,String type) {
Pizza pizza = null;
if (style.equals("NY")) {
if (type.equals("cheese")) {
pizza = new NYStyleCheesePizza();
} else if (type.equals("veggie")) {
pizza = new NYStyleVeggiePizza();
} else if (type.equals("clam")) {
pizza = new NYStyleClamPizza();
} else if (type.equals("pepperoni")) {
pizza = new NYStylePepperoniPizza();
}
} else if (style.equals("Chicago")) {
if (type.equals("cheese")) {
pizza = new ChicagoStyleCheesePizza();
} else if (type.equals("veggie")) {
pizza = new ChicagoStyleVeggiePizza();
} else if (type.equals("clam")) {
pizza = new ChicagoStyleClamPizza();
} else if (type.equals("pepperoni")) {
pizza = new ChicagoStylePepperoniPizza();
}
} else {
System.out.println("Error: invalid type of pizza");
return null;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.Box();
return pizza;
}
}
解决方法
DependentPizzaStore
需要明确了解所有实现才能初始化它们。因此,DependentPizzaStore
依赖于这些实现并紧密耦合。如果这些实现的构造函数中的任何一个要更改,那么您还需要更改 DependentPizzaStore
抽象工厂将允许您提供一个接口来创建相关或依赖对象的系列,而无需指定它们的具体类。
因为你的例子也有不同风格的披萨
public interface PizzaFactory {
string getStyle();
Pizza createPizza(String type);
}
那么不同的风格就需要不同的工厂。
public class NYStylePizzaFactory implements PizzaFactory {
public string getStyle() { return "NY"; }
public Pizza createPizza(String type) {
Pizza pizza = null;
if (type.equals("cheese")) {
pizza = new NYStyleCheesePizza();
} else if (type.equals("veggie")) {
pizza = new NYStyleVeggiePizza();
} else if (type.equals("clam")) {
pizza = new NYStyleClamPizza();
} else if (type.equals("pepperoni")) {
pizza = new NYStylePepperoniPizza();
}
if(pizza == null){
//...throw?
}
return pizza;
}
}
public class ChicagoStylePizzaFactory implements PizzaFactory {
public string getStyle() { return "Chicago"; }
public Pizza createPizza(String type) {
if (type.equals("cheese")) {
pizza = new ChicagoStyleCheesePizza();
} else if (type.equals("veggie")) {
pizza = new ChicagoStyleVeggiePizza();
} else if (type.equals("clam")) {
pizza = new ChicagoStyleClamPizza();
} else if (type.equals("pepperoni")) {
pizza = new ChicagoStylePepperoniPizza();
}
if(pizza == null){
//...throw?
}
return pizza;
}
}
DependentPizzaStore
现在可以将制作比萨饼的任务委托给工厂,而无需了解有关实施细节的任何信息。
public class DependentPizzaStore {
List<PizzaFactory> factories;
public DependentPizzaStore(List<PizzaFactory> factories) {
this.factories = factories;
}
public Pizza createPizza(String style,String type) {
Pizza pizza = null;
for (PizzaFactory factory : factories) {
if (factory.getStyle().equals(style)) {
pizza = factory.createPizza(type);
break;
}
}
if (pizza == null){
System.out.println("Error: invalid type of pizza");
return null;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
任何其他样式都不会影响或导致商店发生变化。工厂生产比萨的方式发生任何变化也不会影响或导致商店发生变化。
因此,商店依赖于抽象而不是具体。