定义
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例推迟到子类。
UML类图
说明
Prouduct:所有的产品都必须实现这个共同的接口,并实现多态
Creator:它是一个类,实现了所有操纵产品的方法,但不实现工厂方法,并且所有的它的子类都必须实现这个抽象的factoryMethod()方法。
ConcreteCreator:它必须实现factoryMethod(),以实际制造出产品,并且它负责创建一个或多个具体产品,只有ConcreteCreator类知道如何创建这些产品。
事例
上一次的简单工厂,以一个披萨店为例;这里同样如此,说明它如何从一个简单工厂扩展为工厂方法模式;
这里,披萨店要开分店
纽约披萨店:奶酪、蛤蜊、意式辣肠、蔬菜等类型的披萨
芝加哥披萨店:奶酪、蛤蜊、意式辣肠、蔬菜等类型的披萨
两种店都供应这些披萨,但同种名称的披萨的细节却不同,每家店都供应其独特的披萨。
UML类图
代码
Pizza.java 抽象类,披萨超类
package com.jing.factory;
import java.util.ArrayList;
public abstract class Pizza {
String name; // 名字
String dough;// 面包
String sauce;// 酱料
// 佐料
ArrayList<String> topping = new ArrayList<String>();
public String getName() {
return name;
}
public void prepare() {
System.out.println("Preparing " + name);
}
public void bake() {
System.out.println("Baking " + name);
}
public void cut() {
System.out.println("Cutting " + name);
}
public void box() {
System.out.println("Boxing " + 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 < topping.size(); ++i) {
display.append((String) topping.get(i) + "\n");
}
return display.toString();
}
}
ChicagoStyleCheesePizza.java 芝加哥风格的奶酪披萨
package com.jing.factory;
public class ChicagoStyleCheesePizza extends Pizza {
public ChicagoStyleCheesePizza() {
name = "Chiacago Cheese Pizza"; // 奶酪 披萨
dough = "Regular Crust"; // 普通的披萨饼皮
sauce = "Marinara Pizza Sauce"; // 蕃茄酱,沙司
topping.add("Fresh Mozzarella");// 新鲜的马苏里拉奶酪
topping.add("Parmesan");// 芝士
}
public void cut(){
System.out.println("Chicago cutting the pizza into square slices");
}
}
ChicagoStyleClamPizza.java 芝加哥风格的蛤蜊披萨
package com.jing.factory;
public class ChicagoStyleClamPizza extends Pizza {
public ChicagoStyleClamPizza(){
name = "Chiacago Clam Pizza";//蛤蜊
dough = "Thin crust";// 薄的面皮
sauce = "White garlic sauce";//白的蒜酱
topping.add("Clams");
topping.add("Grated Parmesan cheese");// 巴马干酪
}
public void cut(){
System.out.println("Chicago cutting the pizza into square slices");
}
}
ChicagoStylePepperoniPizza.java 芝加哥风格意式辣肠
package com.jing.factory;
public class ChicagoStylePepperoniPizza extends Pizza {
public ChicagoStylePepperoniPizza(){
name = "Chiacago Pepperoni Pizza";//意大利辣肠
dough = "Curst";// 面皮
sauce = "Marinara sauce";// 蕃茄酱
topping.add("Sliced Pepperoni");// 切片辣肠
topping.add("Sliced Onion"); // 切片洋葱
topping.add("Grated parmesan cheese");//芝士奶酪
}
public void cut(){
System.out.println("Chicago cutting the pizza into square slices");
}
}
ChicagoStyleVeggiePizza.java 芝加哥风格的蔬菜披萨
package com.jing.factory;
public class ChicagoStyleVeggiePizza extends Pizza {
public ChicagoStyleVeggiePizza(){
name = "Chiacago Veggie Pizza"; // 蔬菜
dough = "Crust";
sauce = "Marinara sauce";// 蕃茄酱
topping.add("Shredded mozzaredlla");// 意大利干酪
topping.add("Grated parmesan");// 芝士
topping.add("Diced onion");// 切丁洋葱
topping.add("Sliced mushrooms");//切片蘑菇
topping.add("Sliced red pepper");//切片红花椒
topping.add("Sliced black olives");//橄榄
}
public void cut(){
System.out.println("Chicago cutting the pizza into square slices");
}
}
NYStyleCheesePizza.java 纽约风格的奶酪披萨
package com.jing.factory;
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza() {
name = "NY Cheese Pizza"; // 奶酪 披萨
dough = "Regular Crust"; // 普通的披萨饼皮
sauce = "Marinara Pizza Sauce"; // 蕃茄酱,沙司
topping.add("Fresh Mozzarella");// 新鲜的马苏里拉奶酪
topping.add("Parmesan");// 芝士
}
}
NYStyleClamPizza.java 纽约风格的蛤蜊披萨
package com.jing.factory;
public class NYStyleClamPizza extends Pizza {
public NYStyleClamPizza(){
name = "NY Clam Pizza";//蛤蜊
dough = "Thin crust";// 薄的面皮
sauce = "White garlic sauce";//白的蒜酱
topping.add("Clams");
topping.add("Grated Parmesan cheese");// 巴马干酪
}
}
NYStylePepperoniPizza.java 纽约风格的意式辣肠披萨
package com.jing.factory;
public class NYStylePepperoniPizza extends Pizza {
public NYStylePepperoniPizza(){
name = "NY Pepperoni Pizza";//意大利辣肠
dough = "Curst";// 面皮
sauce = "Marinara sauce";// 蕃茄酱
topping.add("Sliced Pepperoni");// 切片辣肠
topping.add("Sliced Onion"); // 切片洋葱
topping.add("Grated parmesan cheese");//芝士奶酪
}
}
NYStyleVeggiePizza.java 纽约风格的蔬菜披萨
package com.jing.factory;
public class NYStyleVeggiePizza extends Pizza {
public NYStyleVeggiePizza(){
name = "NY Veggie Pizza"; // 蔬菜
dough = "Crust";
sauce = "Marinara sauce";// 蕃茄酱
topping.add("Shredded mozzaredlla");// 意大利干酪
topping.add("Grated parmesan");// 芝士
topping.add("Diced onion");// 切丁洋葱
topping.add("Sliced mushrooms");//切片蘑菇
topping.add("Sliced red pepper");//切片红花椒
topping.add("Sliced black olives");//橄榄
}
}
PizzaStore.java 披萨店抽象超类
package com.jing.factory;
//public class PizzaStore {
//改成抽象类
public abstract class PizzaStore {
// SimplePizzaFactory factory;
//
// public PizzaStore(SimplePizzaFactory factory){
// this.factory = factory;
// }
abstract Pizza createPizza(String type);
public Pizza orderPizza(String type){
// pizza = factory.createPizza(type);
Pizza pizza = createPizza(type);
System.out.println("------- Making a " + pizza.getName()+ " --------- ");
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
ChicagoPizzaStore.java 芝加哥披萨店
package com.jing.factory;
public class ChicagoPizzaStore extends PizzaStore{
public Pizza createPizza(String type){
Pizza pizza = null;
if (type.equals("cheese")){
pizza = new ChicagoStyleCheesePizza();
} else if (type.equals("pepperoni")){
pizza = new ChicagoStylePepperoniPizza();
} else if (type.equals("clam")){
pizza = new ChicagoStyleClamPizza();
} else if (type.equals("veggie")){
pizza = new ChicagoStyleVeggiePizza();
}
return pizza;
}
}
NYPizzaStore.java 纽约披萨店
package com.jing.factory;
public class NYPizzaStore extends PizzaStore {
public Pizza createPizza(String type){
Pizza pizza = null;
if (type.equals("cheese")){
pizza = new NYStyleCheesePizza();
} else if (type.equals("pepperoni")){
pizza = new NYStylePepperoniPizza();
} else if (type.equals("clam")){
pizza = new NYStyleClamPizza();
} else if (type.equals("veggie")){
pizza = new NYStyleVeggiePizza();
}
return pizza;
}
}
Test.java 测试类
package com.jing.factory;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 纽约披萨店
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");
pizza = nyStore.orderPizza("clam");
System.out.println("Ethan ordered a " + pizza.getName() + "\n");
pizza = chicagoStore.orderPizza("clam");
System.out.println("Joel ordered a " + pizza.getName() + "\n");
pizza = nyStore.orderPizza("pepperoni");
System.out.println("Ethan ordered a " + pizza.getName() + "\n");
pizza = chicagoStore.orderPizza("pepperoni");
System.out.println("Joel ordered a " + pizza.getName() + "\n");
pizza = nyStore.orderPizza("veggie");
System.out.println("Ethan ordered a " + pizza.getName() + "\n");
pizza = chicagoStore.orderPizza("veggie");
System.out.println("Joel ordered a " + pizza.getName() + "\n");
}
}
输出
------- Making a NY Cheese Pizza ---------
Preparing NY Cheese Pizza
Baking NY Cheese Pizza
Cutting NY Cheese Pizza
Boxing NY Cheese Pizza
Ethan ordered a NY Cheese Pizza
------- Making a Chiacago Cheese Pizza ---------
Preparing Chiacago Cheese Pizza
Baking Chiacago Cheese Pizza
Chicago cutting the pizza into square slices
Boxing Chiacago Cheese Pizza
Joel ordered a Chiacago Cheese Pizza
------- Making a NY Clam Pizza ---------
Preparing NY Clam Pizza
Baking NY Clam Pizza
Cutting NY Clam Pizza
Boxing NY Clam Pizza
Ethan ordered a NY Clam Pizza
------- Making a Chiacago Clam Pizza ---------
Preparing Chiacago Clam Pizza
Baking Chiacago Clam Pizza
Chicago cutting the pizza into square slices
Boxing Chiacago Clam Pizza
Joel ordered a Chiacago Clam Pizza
------- Making a NY Pepperoni Pizza ---------
Preparing NY Pepperoni Pizza
Baking NY Pepperoni Pizza
Cutting NY Pepperoni Pizza
Boxing NY Pepperoni Pizza
Ethan ordered a NY Pepperoni Pizza
------- Making a Chiacago Pepperoni Pizza ---------
Preparing Chiacago Pepperoni Pizza
Baking Chiacago Pepperoni Pizza
Chicago cutting the pizza into square slices
Boxing Chiacago Pepperoni Pizza
Joel ordered a Chiacago Pepperoni Pizza
------- Making a NY Veggie Pizza ---------
Preparing NY Veggie Pizza
Baking NY Veggie Pizza
Cutting NY Veggie Pizza
Boxing NY Veggie Pizza
Ethan ordered a NY Veggie Pizza
------- Making a Chiacago Veggie Pizza ---------
Preparing Chiacago Veggie Pizza
Baking Chiacago Veggie Pizza
Chicago cutting the pizza into square slices
Boxing Chiacago Veggie Pizza
Joel ordered a Chiacago Veggie Pizza