刚刚忽略了一件重要的事,Pizza本身。
public abstract class Pizza {
//每个Pizza都具有名称、面团类型、酱料类型、一套酢料
String name;
String dough;
String sauce;
ArrayList toppings = new ArrayList();
void prepare() {
System.out.println("Preparing " + name);
System.out.println("Tossing dough...");
System.out.println("Adding sauce...");
System.out.println("Adding toppings: ");
for (int i = 0; i < toppings.size(); i++) {
System.out.println(" " + toppings.get(i));
}
}
void bake() {
System.out.println("Bake for 25 minutes at 350");
}
void cut() {
System.out.println("Cutting the pizza into diagonal slices");
}
void box() {
System.out.println("Place pizza in official PizzaStore box");
}
public String getName() {
return name;
}
public String toString() {
StringBuffer display = new StringBuffer();
display.append("---- " + name + " ----\n");
display.append(dough + "\n");
display.append(sauce + "\n");
for (int i = 0; i < toppings.size(); i++) {
display.append((String )toppings.get(i) + "\n");
}
return display.toString();
}
}
以下罗列一些具体的pizza子类
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza() {
name = "NY Style Sauce and Cheese Pizza";
dough = "Thin Crust Dough";
sauce = "Marinara Sauce";
toppings.add("Grated Reggiano Cheese");
}
}
public class ChicagoStyleCheesePizza extends Pizza {
public ChicagoStyleCheesePizza() {
name = "Chicago Style Deep Dish Cheese Pizza";
dough = "Extra Thick Crust Dough";
sauce = "Plum Tomato Sauce";
toppings.add("Shredded Mozzarella Cheese");
}
//这个Pizza覆盖了cut()方法,将Pizza切成了正方形
void cut() {
System.out.println("Cutting the pizza into square slices");
}
}
具体的PizzaStroe类
public class NYPizzaStore extends PizzaStore {
Pizza createPizza(String item) {
if (item.equals("cheese")) {
return new NYStyleCheesePizza();
} else if (item.equals("veggie")) {
return new NYStyleVeggiePizza();
} else if (item.equals("clam")) {
return new NYStyleClamPizza();
} else if (item.equals("pepperoni")) {
return new NYStylePepperoniPizza();
} else return null;
}
}
测试类
public class PizzaTestDrive {
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 = chicagoStore.orderPizza("cheese");
System.out.println("Joel ordered a " + pizza.getName() + "\n");
}
认识工厂方法模式的时刻终于到了: 所有工厂模式都用来封装对象的创建。 工厂方法模式(Factory Method Pattern)通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。 让我们来看下有哪些组成元素: 1、 创建者类(creator):PizzaStore、NYPizzaStore、ChicagoPizzaStore PizzaStore是抽象创建者类,它定义了一个抽象的工厂方法,让子类实现此方法制造产品。创建者通常会包含依赖于抽象产品的代码,而这些抽象产品由子类制造。创建者不需要真的知道在制造哪种具体产品。 NYPizzaStore、ChicagoPizzaStore是具体创建者类,createPizza()方法是真正的工厂方法,用来制造产品。因为每个加盟店都有自己的PizzaStore子类,所以可以利用实现createPizza()方法创建自己风味的Pizza。 2、 产品类:Pizza以及各个加盟店的产品类(Pizza子类) 平行的类层级:我们已经看到,将一个orderPizza()方法和一个工厂方法联合起来,就可以成为一个框架。除此之外,工厂方法将生产知识封装进各个创建者,这样的做法,也可以被视为一个框架。
定义工厂方法模式:工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。 根据上面PizzaStore的分工我们不难理解,首先有两个很重要父类,FactoryCreator(抽象接口)和Product(产品),通过抽象工厂方法让子类实现制造产品(继承于Product)。
简单工厂和工厂方法模式的区别: 简单工厂把全部事情,都在一个地方处理完了。然而工厂方法却是创建一个框架,让子类决定要如何实现。比方说,在工厂方法中,orderPizza()方法提供了一般的框架,以便创建Pizza,orderPizza()方法依赖工厂方法创建具体类,并制造出实际的Pizza。可通过继承PizzaStore类,决定实际制造出的Pizza是什么。简单工厂的做法,可以将对象的创建封装起来,但是简单工厂不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品。
2.6 抽象工厂模式
代码里减少对于具体类的依赖是件”好事“。