抽象工厂方法中,之所以出现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 {
}