设计模式学习--工厂模式(Factory Pattern)
2013-05-30 13:28
639 查看
设计模式学习--工厂模式(Factory Pattern)
2013年5月30日 设计模式学习记录什么是工厂模式?
工厂模式可分为以下三种类型,需要根据不同需求来决定使用哪一种模式:1. 简单工厂(不是真正意义上的设计模式)
2. 工厂方法(定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类实例化推迟到子类)
3. 抽象工厂(提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类)
面向对象原则:
多用组合,少用继承针对接口编程,不针对实现编程
为交互对象之间的松耦合而努力
类应该对扩展开放,对修改关闭
依赖抽象,不是依赖具体类(新的原则)
要点:
1. 所有的工厂都是用来封装对象的创建。2. 简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。
3. 工厂方法使用继承:把对象的创建委托给子类子类实现工厂方法来创建对象。
4. 抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。
5. 所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。
6. 工厂方法允许类将实例化延迟到子类进行。
7. 抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。
8. 依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象。
9. 工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程。
工厂模式应用实例:比萨店
简单工厂实现
看看UML的类图项目结构:
源代码:
/Pizza.java
package pizzas; import java.util.ArrayList; /*** * 抽象pizza类 * @author wwj * */ abstract public class Pizza { String name; String dough; String sauce; ArrayList toppings = new ArrayList(); public String getName() { return name; } @Override public String toString() { StringBuffer display = new StringBuffer(); display.append("----" + name + "----\n"); display.append(dough + "\n"); display.append(sauce + "\n"); for(int i = 0; i < toppings.size(); i++) { display.append((String)toppings.get(i) + "\n"); } return display.toString(); } //准备 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); } }
package pizzas; /** * 2013/5/25 * @author wwj * */ public class CheesePizza extends Pizza { @SuppressWarnings("unchecked") public CheesePizza() { name = "Cheese Pizza"; dough = "Regular Crust"; sauce = "Marinara Pizza Sauce"; toppings.add("Fresh Mozzarella"); toppings.add("Parmesan"); } }
package pizzas; /** * 2013/5/25 * @author wwj * */ public class ClamPizza extends Pizza { @SuppressWarnings("unchecked") public ClamPizza() { name = "Clam Pizza"; dough = "Thin crust"; sauce = "White garlic sauce"; toppings.add("Clams"); toppings.add("Grated parmesan cheese"); } }
package pizzas; /** * 2013/5/25 * @author wwj * */ public class PepperoniPizza extends Pizza { @SuppressWarnings("unchecked") public PepperoniPizza() { name = "Pepperoni Pizza"; dough = "Crust"; sauce = "Marinara sauce"; toppings.add("Sliced Pepperoni"); toppings.add("Sliced Onion"); toppings.add("Grated parmesan cheese"); } }
package pizzas; /** * 素食pizza * @author wwj * */ public class VegglePizza extends Pizza { @SuppressWarnings("unchecked") public VegglePizza(){ name = "Veggie Pizza"; dough = "Crust"; sauce = "Marinara sauce"; toppings.add("Shredded mozzarella"); toppings.add("Grated parmesan"); toppings.add("Diced onion"); toppings.add("Sliced mushrooms"); toppings.add("Sliced red pepper"); toppings.add("Sliced black olives"); } }
/SimplePizzaFactory.java
package pizzas; /** * 2013/5/27 * @author wwj * 简单工厂方法 */ public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if(type.equals("cheese")) { pizza = new CheesePizza(); } else if(type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if(type.equals("clam")) { pizza = new ClamPizza(); } else if(type.equals("veggie")) { pizza = new VegglePizza(); } return pizza; } }
/PizzaStore
package pizzas; public class PizzaStore { SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory; } public Pizza orderPizza(String type) { Pizza pizza; pizza = factory.createPizza(type); pizza.prepare(); //准备 pizza.bake(); //烘烤 pizza.cut(); //切片 pizza.box(); //装盒 return pizza; } }
/PizzaTestDriver
package pizzas; /** * 2013/5/25 * @author wwj * 简单工厂的测试类 */ public class PizzaTestDriver { public static void main(String[] args) { SimplePizzaFactory factory = new SimplePizzaFactory(); PizzaStore store = new PizzaStore(factory); Pizza pizza = store.orderPizza("cheese"); System.out.println("We ordered a " + pizza.getName() + "\n"); pizza = store.orderPizza("veggie"); System.out.println("We ordered a " + pizza.getName() + "\n"); } }
工厂方法模式实现
项目结构:
/Pizza.java
把Pizza声明为抽象的,让所有具体比萨都必须派生自这个类。package pizzafm; import java.util.ArrayList; /** * 2013/5/25 * @author wwj * */ 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("Tossing dough..."); System.out.println("Adding 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("Place pizza in official PizzaStore box"); } public String getName() { return name; } }
package pizzafm; /** * 纽约披萨 * @author wwj * */ 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"); } }
package pizzafm; public class NYStyleClamPizza extends Pizza { public NYStyleClamPizza() { name = "NY Style Clam Pizza"; dough = "Thin Crust Dough"; sauce = "Marinara Sauce"; toppings.add("Grated Reggiano Cheese"); toppings.add("Fresh Clams from Long Island Sound"); } }
package pizzafm; public class NYStylePepperoniPizza extends Pizza { public NYStylePepperoniPizza() { name = "NY Style Pepperoni Pizza"; dough = "Thin Crust Dough"; sauce = "Marinara Sauce"; toppings.add("Grated Reggiano Cheese"); toppings.add("Sliced Pepperoni"); toppings.add("Garlic"); toppings.add("Onion"); toppings.add("Mushrooms"); toppings.add("Red Pepper"); } }
package pizzafm; 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"); } }
package pizzafm; /** * 芝加哥披萨 * @author wwj * */ 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"); } public void cut() { System.out.println("Cutting the pizza into square slices"); } }
package pizzafm; public class ChicagoStyleClamPizza extends Pizza { public ChicagoStyleClamPizza() { name = "Chicago Style Clam Pizza"; dough = "Extra Thick Crust Dough"; sauce = "Plum Tomato Sauce"; toppings.add("Shredded Mozzarella Cheese"); toppings.add("Frozen Clams from Chesapeake Bay"); } public void cut() { System.out.println("Cutting the pizza into square slices"); } }
package pizzafm; public class ChicagoStylePepperoniPizza extends Pizza { public ChicagoStylePepperoniPizza() { name = "Chicago Style Pepperoni 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"); toppings.add("Sliced Pepperoni"); } public void cut() { System.out.println("Cutting the pizza into square slices"); } }
package pizzafm; 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"); } public void cut() { System.out.println("Cutting the pizza into square slices"); } }
/PizzaStore.java
此类也是声明为抽象的,实例化比萨的责任由具体的子类来实现package pizzafm; /** * 2013/5/25 * @author wwj * 让PizzaStore作为超类,让每个域类型都继承这个PizzaStore,每个子类各自决定如何制造披萨 */ public abstract class PizzaStore { public 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 pizzafm; public class NYPizzaStore extends PizzaStore { @Override Pizza createPizza(String type) { if(type.equals("cheese")){ return new NYStyleCheesePizza(); } else if(type.equals("veggie")) { return new NYStyleVeggiePizza(); } else if(type.equals("clam")) { return new NYStyleClamPizza(); } else if(type.equals("pepperoni")){ return new NYStylePepperoniPizza(); } else return null; } }
package pizzafm; public class ChicagoPizzaStore extends PizzaStore { @Override Pizza createPizza(String type) { if(type.equals("cheese")) { return new ChicagoStyleCheesePizza(); } else if(type.equals("veggie")) { return new ChicagoStyleVeggiePizza(); } else if(type.equals("clam")) { return new ChicagoStyleClamPizza(); } else return null; } }
/PizzaTestDriver.java
package pizzafm; /** * 2013/5/25 * @author wwj * 工厂模式测试驱动类 */ public class PizzaTestDriver { 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.java
package pizzaaf; public abstract class Pizza { String name; Dough dough; Sauce sauce; Veggies veggies[]; Cheese cheese; Pepperoni pepperoni; Clams clam; abstract void prepare(); //声明为抽象,在这个方法中那个我们需要搜集披萨所需的原料,而这些原料当然是来自原料工厂 void bake(){ System.out.println("Bake for 25 minutes at 350"); } void cut() { System.out.println("Cutting the pizza into diagonal slices"); } void box() { System.out.println("Place pizza in official PizzaStore box"); } void setName(String name) { this.name = name; } String getName() { return name; } public String toString() { StringBuffer result = new StringBuffer(); result.append("---- " + name + " ----\n"); if (dough != null) { result.append(dough); result.append("\n"); } if (sauce != null) { result.append(sauce); result.append("\n"); } if (cheese != null) { result.append(cheese); result.append("\n"); } if (veggies != null) { for (int i = 0; i < veggies.length; i++) { result.append(veggies[i]); if (i < veggies.length-1) { result.append(", "); } } result.append("\n"); } if (clam != null) { result.append(clam); result.append("\n"); } if (pepperoni != null) { result.append(pepperoni); result.append("\n"); } return result.toString(); } }
package pizzaaf; public class CheesePizza extends Pizza { PizzaIngredientFactory ingredientFactory; public CheesePizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } @Override void prepare() { System.out.println("Preparing " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); } }
package pizzaaf; public class ClamPizza extends Pizza { PizzaIngredientFactory ingredientFactory; public ClamPizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } @Override void prepare() { System.out.println("PreParing " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); clam = ingredientFactory.createClam(); } }
package pizzaaf; public class PepperoniPizza extends Pizza { PizzaIngredientFactory ingredientFactory; public PepperoniPizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } void prepare() { System.out.println("Preparing " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); veggies = ingredientFactory.createVeggies(); pepperoni = ingredientFactory.createPepperoni(); } }
package pizzaaf; public class VeggiePizza extends Pizza { PizzaIngredientFactory ingredientFactory; public VeggiePizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } void prepare() { System.out.println("Preparing " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); veggies = ingredientFactory.createVeggies(); } }
/PizzaIngredientFactory.java
package pizzaaf; /** * 建造原料工厂 * @author wwj * 在接口中,每个原料都有一个对应的方法创造该原料 */ public interface PizzaIngredientFactory { public Dough createDough(); public Sauce createSauce(); public Cheese createCheese(); public Veggies[] createVeggies(); public Pepperoni createPepperoni(); public Clams createClam(); }
package pizzaaf; /** * 创建纽约原料工厂 * @author wwj * */ public class NYPizzaIngredientFactory implements PizzaIngredientFactory { @Override public Dough createDough() { return new ThinCrustDough(); } @Override public Sauce createSauce() { return new MarinaraSauce(); } @Override public Cheese createCheese() { return new ReggianoCheese(); } @Override public Veggies[] createVeggies() { Veggies veggies[] = {new Garlic(), new Onion(), new MushRoom(), new RedPepper()}; return veggies; } @Override public Clams createClam() { return new FreshClams(); } @Override public Pepperoni createPepperoni() { return new SlicePepproni(); } }
package pizzaaf; /** * 芝加哥披萨原料工厂 * @author wwj * */ public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory { @Override public Dough createDough() { return new ThickCrustDough(); } @Override public Sauce createSauce() { return new plumTomatoSauce(); } @Override public Cheese createCheese() { return new Mozzarella(); } @Override public Veggies[] createVeggies() { Veggies veggies[] = {new BlackOlives(), new Spinach(), new EggPlant()}; return veggies; } @Override public Clams createClam() { return new FrozenClams(); } @Override public Pepperoni createPepperoni() { return new SlicedPepperoni(); } }
所有原料接口,一系列产品族
package pizzaaf; public interface Cheese { @Override public String toString(); }
package pizzaaf; public interface Clams { @Override public String toString(); }
package pizzaaf; public interface Dough { @Override public String toString(); }
package pizzaaf; public interface Sauce { @Override public String toString(); }
package pizzaaf; public interface Veggies { @Override public String toString(); }
package pizzaaf; public interface Pepperoni { @Override public String toString(); }
实现Cheese的类
package pizzaaf; public class Mozzarella implements Cheese { public String toString() { return "Shredded Mozzarella"; } }
package pizzaaf; public class ReggianoCheese implements Cheese { public String toString() { return "Reggiano Cheese"; } }
实现Clams的类
package pizzaaf; public class FreshClams implements Clams { public String toString() { return "Fresh Clams from Long Island Sound"; } }
package pizzaaf; public class FrozenClams implements Clams { public String toString() { return "Frozen Clams from Chesapeake Bay"; } }
实现Sauce的类
package pizzaaf; public class MarinaraSauce implements Sauce { public String toString() { return "Marinara Sauce"; } }
package pizzaaf; public class plumTomatoSauce implements Sauce { public String toString() { return "Tomato sauce with plum tomatoes"; } }
实现Veggies的类
package pizzaaf; public class EggPlant implements Veggies { public String toString() { return "Eggplant"; } }
package pizzaaf; public class Onion implements Veggies { public String toString() { return "Onion"; } }
package pizzaaf; public class Spinach implements Veggies { public String toString() { return "Spinach"; } }
package pizzaaf; public class MushRoom implements Veggies { public String toString() { return "Mushrooms"; } }
实现Pepperoni的类
实现Dough的类
package pizzaaf; public class ThickCrustDough implements Dough { public String toString() { return "ThickCrust style extra thick crust dough"; } }
package pizzaaf; public class ThinCrustDough implements Dough { public String toString() { return "Thin Crust Dough"; } }
关于工厂模式已经介绍完,蛮多内容的是吧。
什么时候用工厂方法和抽象方法呢?
来听听它们的告白:
抽象工厂:我是抽象工厂,当你需要创建产品家族和想让制造的相关产品集合起来时,你可以使用我。
工厂方法:我是工厂方法,我可以把你的客户代码从实例化的具体类中解耦。或者如果你目前还不知道将来需要实例化哪些具体类时,也可以用我。我的使用方式简单,只要把握继承成子类,并实现我的工厂方法就行了。
相关文章推荐
- 设计模式学习--工厂模式(Factory Pattern)
- 设计模式学习(三) -- 工厂模式 Factory Pattern
- 设计模式学习--工厂模式(Factory Pattern)
- 设计模式学习笔记:factory method(工厂方法)
- 【设计模式】创建型模式—— 工厂模式(Factory Pattern)
- 设计模式学习总结-简单工厂模式(Simple Factory Pattern)
- 设计模式学习笔记--工厂(Factory)、建造(Builder)和原型(Prototype)
- 小菜学设计模式 工厂设计模式 Simple Factory Pattern
- 设计模式学习4 Factory Pattern
- 设计模式之工厂模式(Factory Pattern)
- java 设计模式学习笔记二 工厂模式Factory
- Head First 设计模式之工厂模式(Factory Pattern)
- 小菜学设计模式 工厂设计模式 Simple Factory Pattern
- 设计模式学习4 Factory Pattern
- 【设计模式】学习笔记4:简单工厂模式(Simple Factory)
- 设计模式学习笔记四:工厂方法(Factory Method)
- java 设计模式学习笔记二 工厂模式Factory
- 设计模式最简Demo:简单工厂模式[Simple Factory Pattern]
- 设计模式学习笔记三:简单工厂(Simple Factory)
- 设计模式 - 工厂模式(factory pattern) 详解