设计模式-工厂模式
当看到“new”,就会想到“具体”
当遇到一群相关的具体类时,通常见到下面的代码\rPizza orderPizza(String type){\r Pizza pizza;\r if (type.equals(“cheese”)){\r pizza = new CheeasePizza();\r } else if (type.equals(“greek”)){\r pizza = new GreekPizza();\r } else if (type.equals(“pepperoni”)){\r pizza = new PepperoniPizza();\r }\r…\r}
如果增加更多的产品类型怎么办
开始封装创建对象的代码\r建立一个简单工厂\r当需要pizza时,就叫工厂做一个\rPublic class SimplePizzaFactory {\r public Pizza createPizza(String type){\r Pizza pizza=null;\r if (type.equals(“cheese”)){\r pizza = new CheeasePizza();\r } else if (type.equals(“greek”)){\r pizza = new GreekPizza();\r } else if (type.equals(“pepperoni”)){\r pizza = new PepperoniPizza();\r }\r return pizza;\r }\r}
定义简单工厂
public class SimplePizzaFactory {\r\r public Pizza createPizza(String type) {\r Pizza pizza = null;\r\r if (type.equals("cheese")) {\r pizza = new CheesePizza();\r } else if (type.equals("pepperoni")) {\r pizza = new PepperoniPizza();\r } else if (type.equals("clam")) {\r pizza = new ClamPizza();\r } else if (type.equals("veggie")) {\r pizza = new VeggiePizza();\r }\r return pizza;\r }\r}\r
public class PizzaStore {\r SimplePizzaFactory factory;\r \r public PizzaStore(SimplePizzaFactory factory) { \r this.factory = factory;\r }\r \r public Pizza orderPizza(String type) {\r Pizza pizza;\r \r pizza = factory.createPizza(type);\r \r pizza.prepare();\r pizza.bake();\r pizza.cut();\r pizza.box();\r\r return pizza;\r }\r\r}
新的需求\r希望每个地方的pizza店提供不同风味的pizza
一种做法\r利用SimplePizzaFactory,写出三种不同的工厂\rNYPizzaFactory nyFactory =new NYPizzaFactory ();\rPizzaStore nyStore = new PizzaStore (nyFactory);\rnyStore.orderPizza(“Veggie”);
但是制作pizza的过程需要规范统一\r方法\r将createPizza()方法放回到PizzaStore中\r将它设置为抽象方法\r\r
Public abstract class PizzaStore {\r public Pizza orderPizza(String type){\r Pizza pizza;\r pizza = createPizaa(type);\r pizza.prepare();\r pizza.bake();\r pizza.cut();\r pizza.box();\r return pizza;\r }\r abstract Pizza createPizza(String type);\r}
public class NYPizzaStore extends PizzaStore {\r\r Pizza createPizza(String item) {\r if (item.equals("cheese")) {\r return new NYStyleCheesePizza();\r } else if (item.equals("veggie")) {\r return new NYStyleVeggiePizza();\r } else if (item.equals("clam")) {\r return new NYStyleClamPizza();\r } else if (item.equals("pepperoni")) {\r return new NYStylePepperoniPizza();\r } else return null;\r }\r}
public abstract class Pizza {\r String name;\r String dough;\r String sauce;\r ArrayList toppings = new ArrayList();\r \r void prepare() {\r System.out.println("Preparing " name);\r System.out.println("Tossing dough...");\r System.out.println("Adding sauce...");\r System.out.println("Adding toppings: ");\r for (int i = 0; i < toppings.size(); i ) {\r System.out.println(" " toppings.get(i));\r }\r }\r \r void bake() {\r System.out.println("Bake for 25 minutes at 350");\r }\r \r void cut() {\r System.out.println("Cutting the pizza into diagonal slices");\r }\r \r void box() {\r System.out.println("Place pizza in official PizzaStore box");\r }\r \r public String getName() {\r return name;\r }\r\r public String toString() {\r StringBuffer display = new StringBuffer();\r display.append("---- " name " ----\n");\r display.append(dough "\n");\r display.append(sauce "\n");\r for (int i = 0; i < toppings.size(); i ) {\r display.append((String )toppings.get(i) "\n");\r }\r return display.toString();\r }\r}
public class NYStyleCheesePizza extends Pizza {\r\r public NYStyleCheesePizza() { \r name = "NY Style Sauce and Cheese Pizza";\r dough = "Thin Crust Dough";\r sauce = "Marinara Sauce";\r \r toppings.add("Grated Reggiano Cheese");\r }\r}
认识工厂模式
工厂模式都用来封装对象的创建\r通过让子类决定该创建的对象是什么\r涉及到的元素\rCreator类
\r产品类
定义工厂方法模式
工厂方法模式定义了一个创建对象的接口\r由子类决定实例化的类是哪一个
依赖倒置原则
要依赖抽象,不要依赖具体类\r不使用工厂设计模式\rPublic class PizzaStore {\r public Pizza createPizza(String style, String type) {\r Pizza pizza=null;\r if (style.equals(“NY”)){\r if (type.equals(“cheese”)){\r pizza=new NYStyleCheesePizza();\r }else if \r }else if\r }else {\r }\r }\r}\rPizzaStore这个高层组件非常依赖具体的低层组件pizza类
应用依赖倒置原则\r应用工厂方法\r高层组件(PizzaStore)和低层组件都依赖了Pizza抽象
遵循倒置依赖原则的指导方针
变量不可以持有具体类的引用\r如果使用new,就会持有具体类的引用\r可以改用工厂来避开这样的做法\r不要让类派生自具体类\r如果派生自具体类,就会依赖具体类\r请派生自一个抽象(接口或抽象类)\r不是随时都要遵循这个原则\r如直接实例化字符串对象
新需求
建造一个原料工厂,为加盟店统一配送原料,保证原料的可靠\r为了各个加盟店的风味,需要多组不同的原料
建造原料工厂\rpublic interface PizzaIngredientFactory {\r \r public Dough createDough();\r public Sauce createSauce();\r public Cheese createCheese();\r public Veggies[] createVeggies();\r public Pepperoni createPepperoni();\r public Clams createClam();\r \r}
实现一个原料工厂
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {\r \rpublic Dough createDough() {\rreturn new ThinCrustDough();\r}\r \rpublic Sauce createSauce() {\rreturn new MarinaraSauce();\r}\r \rpublic Cheese createCheese() {\rreturn new ReggianoCheese();\r}\r \rpublic Veggies[] createVeggies() {\rVeggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };\rreturn veggies;\r}\r \rpublic Pepperoni createPepperoni() {\rreturn new SlicedPepperoni();\r}\r\rpublic Clams createClam() {\rreturn new FreshClams();\r}\r}
public abstract class Pizza {\rString name;\r\rDough dough;\rSauce sauce;\rVeggies veggies[];\rCheese cheese;\rPepperoni pepperoni;\rClams clam;\r\rabstract void prepare();\r\rvoid bake() {\rSystem.out.println("Bake for 25 minutes at 350");\r}\r\rvoid cut() {\rSystem.out.println("Cutting the pizza into diagonal slices");\r}\r\rvoid box() {\rSystem.out.println("Place pizza in official PizzaStore box");\r}\r\rvoid setName(String name) {\rthis.name = name;\r}\r\rString getName() {\rreturn name;\r}\r\rpublic String toString() {\r}\r}
public class CheesePizza extends Pizza {\r PizzaIngredientFactory ingredientFactory;\r \r public CheesePizza(PizzaIngredientFactory ingredientFactory) {\r this.ingredientFactory = ingredientFactory;\r }\r \r void prepare() {\r System.out.println("Preparing " name);\r dough = ingredientFactory.createDough();\r sauce = ingredientFactory.createSauce();\r cheese = ingredientFactory.createCheese();\r }\r}
public abstract class PizzaStore {\r \rprotected abstract Pizza createPizza(String item);\r \rpublic Pizza orderPizza(String type) {\rPizza pizza = createPizza(type);\rSystem.out.println("--- Making a " pizza.getName() " ---");\rpizza.prepare();\rpizza.bake();\rpizza.cut();\rpizza.box();\rreturn pizza;\r}\r}
public class NYPizzaStore extends PizzaStore {\r \rprotected Pizza createPizza(String item) {\rPizza pizza = null;\rPizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();\r \rif (item.equals("cheese")) {\r \rpizza = new CheesePizza(ingredientFactory);\rpizza.setName("New York Style Cheese Pizza");\r \r} else if (item.equals("veggie")) {\r \rpizza = new VeggiePizza(ingredientFactory);\rpizza.setName("New York Style Veggie Pizza");\r \r} else if (item.equals("clam")) {\r \rpizza = new ClamPizza(ingredientFactory);\rpizza.setName("New York Style Clam Pizza");\r \r} else if (item.equals("pepperoni")) {\r\rpizza = new PepperoniPizza(ingredientFactory);\rpizza.setName("New York Style Pepperoni Pizza");\r \r} \rreturn pizza;\r}\r}\r
定义抽象工厂模式
比较工厂方法和抽象方法
抽象工厂的需求:创建一个产品家族\r负责在抽象工厂中创建产品的方法,通常是以“工厂方法”来实现的