深入显出设计模式四——比萨店生产比萨实现(工厂方法模式)
深入浅出设计模式四——比萨店生产比萨实现(工厂方法模式)
在http://quicker.iteye.com/blog/571714一文中已经讲了简单工厂和工厂方法并且有UML图和实现的代码。
这里只结合实例分析一下工厂方法在实际生活中的应用。
我们看看比萨店及比萨的图。
产品图。
结合http://quicker.iteye.com/blog/571714中关于工厂方法模式的实现,不难得出实现代码:
package com.lwf.disign.learn.factorymethod; public abstract class PizzaStore { public final Pizza orderPizza(String type){ Pizza pizza; pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } abstract Pizza createPizza(String type); }
package com.lwf.disign.learn.factorymethod; public class NYPizzaStore extends PizzaStore { Pizza createPizza(String type) { Pizza pizza = null; if(type.equals("cheese")){ pizza = new NYCheesePizza(); }else if(type.equals("veggle")){ pizza = new NYVegglePizza(); } return pizza; } }
package com.lwf.disign.learn.factorymethod; public class ChicagoPizzaStore extends PizzaStore { Pizza createPizza(String type) { Pizza pizza = null; if(type.equals("cheese")){ pizza = new ChicagoCheesePizza(); }else if(type.equals("veggle")){ pizza = new ChicagoVegglePizza(); } return pizza; } }
package com.lwf.disign.learn.factorymethod; import java.util.ArrayList; public abstract class Pizza { String name; //名称 String dough; //面团类型 String sauce; //酱料类型 ArrayList toppings = new ArrayList(); //一套佐料 public void prepare() { System.out.println("Preparing " + name); System.out.println("Tossign dough..." + dough); System.out.println("Adding sauce..." + sauce); System.out.println("Adding toppings: "); for (int i = 0; i < toppings.size(); i++) { System.out.println(" " + toppings.get(i)); } } public void bake() { System.out.println("Bake for 25 minutes at 350"); } public void cut() { System.out.println("Cutting the pizza into diagonal slices"); } public void box() { System.out.println("Pizza in offical PizzaStrore box"); } public String getName(){ return name; } }
package com.lwf.disign.learn.factorymethod; public class NYCheesePizza extends Pizza { public NYCheesePizza(){ name = "NYCheesePizza"; dough = "Thin crust dough NYCheesePizza"; sauce = "Marina sauce NYCheesePizza"; toppings.add("Grated NYCheesePizza cheese"); } public void cut(){ System.out.println("cut it into NYCheesePizza slices"); } }
package com.lwf.disign.learn.factorymethod; public class NYVegglePizza extends Pizza { public NYVegglePizza(){ name = "NYVegglePizza"; dough = "Thin crust dough NYVegglePizza"; sauce = "Marina sauce NYVegglePizza"; toppings.add("Grated NYVegglePizza cheese"); } public void cut(){ System.out.println("cut it into NYVegglePizza slices"); } }
package com.lwf.disign.learn.factorymethod; public class ChicagoCheesePizza extends Pizza { public ChicagoCheesePizza(){ name = "ChicagoCheesePizza"; dough = "Thin crust dough ChicagoCheesePizza"; sauce = "Marina sauce ChicagoCheesePizza"; toppings.add("Grated ChicagoCheesePizza cheese"); } public void cut(){ System.out.println("cut it into ChicagoCheesePizza slices"); } }
package com.lwf.disign.learn.factorymethod; public class ChicagoVegglePizza extends Pizza { public ChicagoVegglePizza(){ name = "ChicagoVegglePizza"; dough = "Thin crust dough ChicagoVegglePizza"; sauce = "Marina sauce ChicagoVegglePizza"; toppings.add("Grated ChicagoVegglePizza cheese"); } public void cut(){ System.out.println("cut it into ChicagoVegglePizza slices"); } }
上面共定义了四种比萨,客户向系统订购这四种比萨。。
package com.lwf.disign.learn.factorymethod; public class PizzaStoreTest { public static void main(String[] args) { PizzaStore pizzaStore = new NYPizzaStore(); Pizza pizza = pizzaStore.orderPizza("cheese"); print(pizza.getName()); pizza = pizzaStore.orderPizza("veggle"); print(pizza.getName()); pizzaStore = new ChicagoPizzaStore(); pizza = pizzaStore.orderPizza("cheese"); print(pizza.getName()); pizza = pizzaStore.orderPizza("veggle"); print(pizza.getName()); } public static void print(String name){ System.out.println(name); System.out.println("-------------------------"); } }
输出结果为:
Preparing NYCheesePizza Tossign dough...Thin crust dough NYCheesePizza Adding sauce...Marina sauce NYCheesePizza Adding toppings: Grated NYCheesePizza cheese Bake for 25 minutes at 350 cut it into NYCheesePizza slices Pizza in offical PizzaStrore box NYCheesePizza ------------------------- Preparing NYVegglePizza Tossign dough...Thin crust dough NYVegglePizza Adding sauce...Marina sauce NYVegglePizza Adding toppings: Grated NYVegglePizza cheese Bake for 25 minutes at 350 cut it into NYVegglePizza slices Pizza in offical PizzaStrore box NYVegglePizza ------------------------- Preparing ChicagoCheesePizza Tossign dough...Thin crust dough ChicagoCheesePizza Adding sauce...Marina sauce ChicagoCheesePizza Adding toppings: Grated ChicagoCheesePizza cheese Bake for 25 minutes at 350 cut it into ChicagoCheesePizza slices Pizza in offical PizzaStrore box ChicagoCheesePizza ------------------------- Preparing ChicagoVegglePizza Tossign dough...Thin crust dough ChicagoVegglePizza Adding sauce...Marina sauce ChicagoVegglePizza Adding toppings: Grated ChicagoVegglePizza cheese Bake for 25 minutes at 350 cut it into ChicagoVegglePizza slices Pizza in offical PizzaStrore box ChicagoVegglePizza -------------------------
设计原则:要依赖抽象,不要依赖具体类,也叫依赖倒置原则
如下图:
可以看到上下都依赖于pizza这个抽象类..
这启发我们思考方式的变化,我们也可以倒置思考方式:如一般你想开个比萨店先会想到要用什么做比萨,考虑一大堆原料等。。。最后才是比萨店。那么我们可以改变思考的方式,我们只需要把比萨先做一个抽象。那们上我们可以开比萨店,下我们可以制作多种类型的比萨。
下面有几种方式可以让我们尽可能的遵守倒置原则
然而上面的三点要求对待程序可谓是严格的。。当然如果一个类以后变化的机会很少,那么为什么不直接new出来呢。如String类。。所以这些都只是让我们的设计变得更好的方针,不能死套在程序上。