Pizza的代码利用相关的工厂生产原料。所生产的原料依赖所使用的工厂,Pizza类根本不关心这些原料,它只知道如何制作Pizza。现在,Pizza和区域原料之间被解耦,无论原料工厂是在洛杉矶山脉还是西北沿岸地区,Pizza类都可以轻易复用,完全没有问题。 再回到Pizza店:
public class NYPizzaStore extends PizzaStore {
protected Pizza createPizza(String item) {
Pizza pizza = null;
//纽约店会用到纽约Pizza原料工厂,由该原料工厂负责生产所有原料
PizzaIngredientFactory ingredientFactory =
new NYPizzaIngredientFactory();
/*
* 把工厂传递给每一个Pizza,以便能从工厂中取得原料
* 对于每一种Pizza,我们实例化一个新的Pizza,并传进该中Pizza所需的工厂,以便Pizza取得它的原材料
*/
if (item.equals("cheese")) {
pizza = new CheesePizza(ingredientFactory);
pizza.setName("New York Style Cheese Pizza");
} else if (item.equals("veggie")) {
pizza = new VeggiePizza(ingredientFactory);
pizza.setName("New York Style Veggie Pizza");
} else if (item.equals("clam")) {
pizza = new ClamPizza(ingredientFactory);
pizza.setName("New York Style Clam Pizza");
} else if (item.equals("pepperoni")) {
pizza = new PepperoniPizza(ingredientFactory);
pizza.setName("New York Style Pepperoni Pizza");
}
return pizza;
}
}
我们到底做了些什么? 我们引入新类型的工厂,也就是所谓抽象工厂,来创建原料家族。 通过抽象工厂所提供的接口,可以创建产品的家族,利用这个接口书写代码,我们的代码将从实际工厂解耦,以便在不同上下文中实现各式各样的工厂,制造出各种不同的产品。例如:不同的区域、不同的操作 系统、不同的外观及操作。 因为代码从实际的产品中解耦,所以我们可以替换不同的工厂来取得不同的行为。
定义抽象工厂模式:提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体的类。 抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道(或关心)实际产出的具体产品是什么。这样依赖,客户就从具体的产品中被解耦。
3 本章小结
好长的一章啊,这一章我们学习了简单工厂、工厂方法模式和抽象工厂模式。 这三者在文字定义上就已经把我们搞混淆了,三者间具体的区别唯有经过码农们在实际应用中的使用才能够细细体会。 以下罗列本章的一些要点,来看看你是不是真正理解了这些概念: 1、所有的工厂都是用来封装对象的创建。 2、简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。 3、工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。 4、抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。 5、所有工厂模式都通过减少应用程序与具体类之间的依赖促进松耦合。 6、工厂方法允许类将实例化延迟到子类进行。 7、抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。 8、依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象。 9、工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程。