抽象工厂方法中,之所以出现CheesePizza这个类,是因为工厂中pizza的馅料不同而已,不管是NY还是chicago制作cheesePizza的方法一样。这种馅料的差异放到了原料工厂去处理,完全没有必要设计两种不同的处理cheesepizza的类。
以下是headfirst书中关于抽象工厂模式例子的类图:
抽象工厂模式和公车模式的区别在于:
工厂模式 | 抽象工厂模式 | |
创建对象方法 | 继承,用子类覆盖父类方法,并在子类中创建对象 | 对象的组合,实例化对象,并将其作为参数处理,在工厂接口所暴露出的方法中实现创建 |
工厂对象数量 | 一个工厂产品 | 若干工厂产品 |
抽象工厂方法在创建具体产品时,还是会使用工厂方法。实现创建产品族的关键在于定义一个大的产品抽象接口。
工厂就是用来实现对象创建的。这样做的好处是将客户和实现功能的具体类解耦。这点简单工厂也可以实现。
以下是Head First书中pizza店的Java版本实现:
package org.neomc;
//工厂原料接口定义
public interface PizzaIngredientFactory {
public Dough createDough();
public Sauce createSauce();
}
//工厂原料接口的实现
package org.neomc;
public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
public Dough createDough() {
return new NYDough();
}
public Sauce createSauce() {
return new NYSauce();
}
}
//pizza店的抽象creator类
package org.neomc;
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
public abstract Pizza createPizza(String type);
}
//NY pizza店的实现
package org.neomc;
public class NYPizzaStore extends PizzaStore{
public Pizza createPizza(String type) {
Pizza pizza = null;
NYPizzaIngredientFactory NYFactory = new NYPizzaIngredientFactory();
if(type.equals("NYCheese")) {
pizza = new CheesePizza(NYFactory);
pizza.setName("NY style cheese Pizza");
}
return pizza;
}
}
package org.neomc; //pizza抽象类的实现 public abstract class Pizza { String name; Dough dough; Sauce sauce; public abstract void prepare(); public void bake() { System.out.println("This is baked in" + name); } public void cut() { System.out.println("This is cut in " + name); } public void box() { System.out.println("This is boxed in " + name); } public String getName() { return name; } public void setName(String n) { name = n; } }
//Sauce的一个实现,NY sauce package org.neomc; public class NYSauce extends Sauce{ public NYSauce() { System.out.println("This is NY style Sauce"); } }
//制作一个NY的pizza的调用方法 package org.neomc; public class order { public static void main(String[] args) { PizzaStore myOrder = new NYPizzaStore(); myOrder.orderPizza("NYCheese"); } }
//pizza抽象类的实现 package org.neomc; public abstract class Pizza { String name; Dough dough; Sauce sauce; public abstract void prepare(); public void bake() { System.out.println("This is baked in" + name); } public void cut() { System.out.println("This is cut in " + name); } public void box() { System.out.println("This is boxed in " + name); } public String getName() { return name; } public void setName(String n) { name = n; } }
//cheese pizza的实现,不管NY还是其他地区的cheese pizza的实现方法都一样 package org.neomc; public class CheesePizza extends Pizza { PizzaIngredientFactory factory;//这里并不是对接口的实例化,而是引用。Java不允许接口被实例化 //接口可以被声明出来,但决不能实例化,它可以作为子类的句柄指向子类的实例,但是不能通过它来调用子类所特有的方法 public CheesePizza( PizzaIngredientFactory factory ) { System.out.println("creating cheese pizza"); this.factory = factory; } public void prepare() { System.out.println("preparing " + name); dough = factory.createDough(); sauce = factory.createSauce(); } }
//dough 抽象类定义 package org.neomc; public class Dough { }
//NY dough的一个实现 package org.neomc; public class NYDough extends Dough{ public NYDough() { System.out.println("This is NY style dough"); } }
//Sauce的抽象类 package org.neomc; public class Sauce { }