定义:提供一个接口, 用于创建相关或依赖对象的家族, 而不需要具体类;
抽象工厂模式允许客户使用抽象的接口来创建一组相关的产品, 而不需要知道或关系实际产出的具体产品是什么, 这样一来, 客户就从具体的产品中被解耦。
抽象工厂模式是从前面的工厂方法模式演变而来。 依然由pizzaStore来举例。 我们从原料入手, 每种pizza的制作方法和流程都一样, 由pizza类控制, 不同是各种原料。 比如cheesePizza,原料有:Sauce、Dough, Cheese; 对于不同地区, 原料风味不同,如纽约风味的cheesePizza:MarinaraSauce、ThinCrustDough、ReggianoCheese, 芝加哥风味的cheesePizza:PlumTomatoSauce、ThinCrustDough、MozzarellaCheese;
现在我们要建造一个工厂来生产原料, 这个工厂负责创建原料家族中的每一种原料。 接下来我们在程序中来处理各个区域的差异。
1、原料生产工厂:
PizzaIngredientFactory.java
Dough、Sauce、Cheese、Veggies、Clams这几个是原料类。
public interface PizzaIngredientFactory {
public Dough CreateDoufh();
public Sauce CreateSauce();
public Cheese CreateCheese();
public Veggies[] CreateVeggies();
public Clams CreateClams();
}
纽约原料加工厂
NYPizzaIngredientFactory.java
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
@Override
public Dough CreateDoufh() {
return new Dough("ThinCrust");
}
@Override
public Sauce CreateSauce() {
return new Sauce("Marinara");
}
@Override
public Cheese CreateCheese() {
return new Cheese("Reggiano");
}
@Override
public Veggies[] CreateVeggies() {
Veggies veggies[] = {new Veggies("Garlic"), new Veggies("Onion"), new Veggies("Mushroom")};
return veggies;
}
@Override
public Clams CreateClams() {
return new Clams("Fresh");
}
}
芝加哥原料加工厂
ChicagoPizzaIngredientFactory.java
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
@Override
public Dough CreateDoufh() {
return new Dough("ThinCrust");
}
@Override
public Sauce CreateSauce() {
return new Sauce("PlumTomato");
}
@Override
public Cheese CreateCheese() {
return new Cheese("Mozzarella");
}
@Override
public Veggies[] CreateVeggies() {
Veggies veggies[] = {new Veggies("BlackOlives"), new Veggies("EggPlant"), new Veggies("Spinach")};
return veggies;
}
@Override
public Clams CreateClams() {
return new Clams("Frozen");
}
}
2、pizza类
1)、pizza基础类:pizza.java
public abstract class Pizza {
protected String name;
protected Dough dough;
protected Sauce sauce;
protected Veggies veggies[];
protected Cheese cheese;
protected Clams clam;
public abstract void Prepare();
public void bake() {
System.out.println("Bake for 25 minutes at 350");
}
public void cut() {
System.out.println("Cutting the pizza into diagonal slices");
}
public void box() {
System.out.println("Place pizza in official PizzaStore box ");
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
2)、CheesePizza.java
我们通过制定PizzaIngredientFactory来制定口味
public class CheesePizza extends Pizza {
PizzaIngredientFactory ingredientFactory;
public CheesePizza (PizzaIngredientFactory ingredientFactory) {
this.ingredientFactory = ingredientFactory;
}
@Override
public void Prepare() {// 这里的原料是根据口味,不同的区域工厂生产提供
System.out.println("Preparing " + name);
System.out.println("ingredient:");
dough = ingredientFactory.CreateDoufh();
sauce = ingredientFactory.CreateSauce();
cheese = ingredientFactory.CreateCheese();
}
}
3)、VeeggiePizza.java
public class VeggiePizza extends Pizza {
PizzaIngredientFactory ingredientFactory;
public VeggiePizza (PizzaIngredientFactory ingredientFactory) {
this.ingredientFactory = ingredientFactory;
}
@Override
public void Prepare() {
System.out.println("Preparing " + name);
dough = ingredientFactory.CreateDoufh();
sauce = ingredientFactory.CreateSauce();
cheese = ingredientFactory.CreateCheese();
veggies = ingredientFactory.CreateVeggies();
}
}
其他的ClamPizza等省略, 与上面实现方法相同;
3、pizzaStore
1)、抽象类PizzaStore.java
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza;
pizza = createPizza(type);
pizza.Prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
protected abstract Pizza createPizza(String type);
}
2)NYPizzaStore.java
public class NYPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if (type.equals("cheese")) {
pizza = new CheesePizza(ingredientFactory);
pizza.setName("New York Style Cheese Pizza");
}else if (type.equals("veggie")) {
pizza = new VeggiePizza(ingredientFactory);
pizza.setName("New York Style Veggie Pizza");
}else if (type.equals("clam")) {
pizza = new ClamPizza(ingredientFactory);
pizza.setName("New York Style ClamP Pizza");
}
return pizza;
}
}
3)ChicagoPizzaStore.jva
public class ChicagoPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory();
if (type.equals("cheese")) {
pizza = new CheesePizza(ingredientFactory);
pizza.setName("Chicago Style Cheese Pizza");
}else if (type.equals("veggie")) {
pizza = new VeggiePizza(ingredientFactory);
pizza.setName("Chicago Style Veggie Pizza");
}else if (type.equals("clam")) {
pizza = new ClamPizza(ingredientFactory);
pizza.setName("Chicago Style ClamP Pizza");
}
return pizza;
}
}
PizzaMain.java
public class PizzaMain {
public static void main(String[] args) {
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
System.out.println("Ethan ordered a" + pizza.getName() + "\n");
Pizza pizza2 = chicagoStore.orderPizza("cheese");
System.out.println("Joel ordered a" + pizza2.getName() + "\n");
Pizza pizza3 = chicagoStore.orderPizza("veggie");
System.out.println("Lucy ordered a" + pizza3.getName() + "\n");
}
}
参考:《Head First设计模式》