工厂模式
2018-01-22 本文已影响17人
阳光的技术小栈
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
示例—披萨店
一家披萨店,有很多种口味的披萨可接收下单。为了扩展加盟店,每个披萨从制作到最后出炉,都有一套统一标准化的流程。流程包括准备所有的披萨的配料、准备制作(加酱料、揉面团等)、烘烤、切角、装盒。披萨本身有自己的名称、需要的生面团、酱料以及其他配料。现有纽约和芝加哥两个加盟店,虽然他们店中的披萨种类都一样,但实际出来的口味是不同的,比如纽约芝士披萨(大蒜蕃茄酱以及薄饼)和芝加哥芝士披萨(小蕃茄酱以及厚饼)。所有加盟店的流程以及披萨的种类都是一致的。
UML图表示

代码演示
披萨抽象基类
package Factory;
import java.util.ArrayList;
public abstract class 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");
}
void box(){
System.out.println("Place pizza in official PizzaStore box");
}
public String getName() {
return name;
}
}
纽约披萨子类
package Factory;
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");
}
}
芝加哥披萨子类
package Factory;
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");
}
@Override
void cut(){
System.out.println("Cutting the pizza into square slices");
}
}
披萨店抽象基类
package Factory;
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);
}
纽约披萨店子类
package Factory;
public class NYPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
if (type.equals("cheese")) {
return new NYStyleCheesePizza();
}
else if (type.equals("veggie")){
// return new NYStyleVeggiePizza();
}
else if (type.equals("clam")){
// return new NYStyleClamPizza();
}
else if (type.equals("pepperoni")){
// return new NYStylePepperoniPizza();
}
return null;
}
}
芝加哥披萨店子类
package Factory;
public class ChicagoPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
if (type.equals("cheese")) {
return new ChicagoStyleCheesePizza();
}
else if (type.equals("veggie")){
// return new ChicagoStyleVeggiePizza();
}
else if (type.equals("clam")){
// return new ChicagoStyleClamPizza();
}
else if (type.equals("pepperoni")){
// return new ChicagoStylePepperoniPizza();
}
return null;
}
}
披萨下单测试代码
package Factory;
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");
}
}
测试结果
Preparing NY Style Sauce and Cheese Pizza
Tossing dough...
Adding sauce...
Adding toppings:
Grated Reggiano Cheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal
Place pizza in official PizzaStore box
Ethan ordered a NY Style Sauce and Cheese Pizza
Preparing Chicago Style Deep Dish Cheese Pizza
Tossing dough...
Adding sauce...
Adding toppings:
Shredded Mozzarella Cheese
Bake for 25 minutes at 350
Cutting the pizza into square slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Deep Dish Cheese Pizza