接着简单工厂模式,来个续集,工厂方法模式。
在上一集中,披萨店卖的很火,你赚的是盆满钵满,后面要加入加盟店(比如:纽约,芝加哥等),每一家加盟店制造的披萨又不一样,有芝加哥奶酪披萨(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,到此结束,谢谢收看。。。