接着简单工厂模式,来个续集,工厂方法模式。
在上一集中,披萨店卖的很火,你赚的是盆满钵满,后面要加入加盟店(比如:纽约,芝加哥等),每一家加盟店制造的披萨又不一样,有芝加哥奶酪披萨(ChicagoStyleCheesePizza),芝加哥素披萨(ChicagoStyleVeggiePizza),纽约奶酪披萨(NYStyleCheesePizza),纽约素披萨(NYStyleVeggiePizza),此时怎么办?
什么模式都不用的披萨店代码:
/**
* 独立披萨店
*/
public class DependentPizzaStore {
public Pizza createPizza(String style, String type) {
Pizza pizza = null;
if (style.equals("NY")) {
if (type.equals("cheese")) {
pizza = new NYStyleCheesePizza();
} else if (type.equals("veggie")) {
pizza = new NYStyleVeggiePizza();
}
} else if (style.equals("Chicago")) {
if (type.equals("cheese")) {
pizza = new ChicagoStyleCheesePizza();
} else if (type.equals("veggie")) {
pizza = new ChicagoStyleVeggiePizza();
}
} else {
System.out.println("Error: invalid type of pizza");
return null;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
/**
* 芝加哥奶酪披萨
*/
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");
}
/**
* 披萨跟以前不一样,得切成方形
*/
void cut() {
System.out.println("Cutting the pizza into square slices");
}
}
/**
* 芝加哥素披萨
*/
public class ChicagoStyleVeggiePizza extends Pizza {
public ChicagoStyleVeggiePizza() {
name = "Chicago Deep Dish Veggie Pizza";
dough = "Extra Thick Crust Dough";
sauce = "Plum Tomato Sauce";
toppings.add("Shredded Mozzarella Cheese");
toppings.add("Black Olives");
toppings.add("Spinach");
toppings.add("Eggplant");
}
/**
* 披萨跟以前不一样,得切成方形
*/
void cut() {
System.out.println("Cutting the pizza into square slices");
}
}
/**
* 纽约奶酪披萨
*/
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 NYStyleVeggiePizza extends Pizza {
public NYStyleVeggiePizza() {
name = "NY Style Veggie Pizza";
dough = "Thin Crust Dough";
sauce = "Marinara Sauce";
toppings.add("Grated Reggiano Cheese");
toppings.add("Garlic");
toppings.add("Onion");
toppings.add("Mushrooms");
toppings.add("Red Pepper");
}
}
对于DependentPizzaStore类中,包括两种元素:创建者(纽约披萨店,芝加哥披萨店),产品类(纽约奶酪披萨,纽约素披萨...),此时如果用简单工厂模式,那得传两个参数:创建者类型,产品类型,
对于中情况,我们有更好的模式可以用一下,OK,下面工厂方法模式就可以出场了,老规矩,先贴代码,在讲定义理论
/**
* 披萨店
*
*/
public abstract class PizzaStore {
/**
* 抽象方法
*/
abstract Pizza createPizza(String item);
/**
* 订购披萨
*/
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type);
System.out.println("--- Making a " + pizza.getName() + " ---");
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
/**
* 芝加哥披萨店
*/
public class ChicagoPizzaStore extends PizzaStore {
Pizza createPizza(String item) {
if (item.equals("cheese")) {
return new ChicagoStyleCheesePizza();
} else if (item.equals("veggie")) {
return new ChicagoStyleVeggiePizza();
} else if (item.equals("clam")) {
return new ChicagoStyleClamPizza();
} else if (item.equals("pepperoni")) {
return new ChicagoStylePepperoniPizza();
} else return null;
}
}
/**
* 纽约披萨店
*/
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");
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");
}
}
OK,代码完工,可以看出,披萨的生产是由具体的子类披萨店来生产的,披萨店将生产披萨方法(createPizza)写为抽象方法,而在芝加哥披萨店(ChicagoPizzaStore)和纽约披萨店(NYPizzaStore)生产出来
这就是工厂方法模式。具体定义:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类中。工厂方法模式类图如下:(倒,貌似我没找到贴图的方法,暂时以附件形式上传,
找到方法在贴出来)
结合前面简单工厂模式,那简单工厂模式和工厂方法模式的区别是什么?
1.简单工厂把全部事情,在一个地方都处理完了,然而工厂方法却创建了一个框架,让子类决定如何实现
2.简单工厂,是将对象的创建封装起来,但是简单工厂不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品(工厂方法的创建者子类继承父类,当换成另一个子类,就可以换产品,其实就是面向接口编程)
OK,到此结束,谢谢收看。。。