素材巴巴 > 程序开发 >

设计模式学习--工厂模式(Factory Pattern)

程序开发 2023-09-12 13:40:22

设计模式学习--工厂模式(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;}@Overridepublic 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 {@OverridePizza 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 {@OverridePizza 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;}@Overridevoid 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;}@Overridevoid 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 {@Overridepublic Dough createDough() {return new ThinCrustDough();}@Overridepublic Sauce createSauce() {return new MarinaraSauce();}@Overridepublic Cheese createCheese() {return new ReggianoCheese();}@Overridepublic Veggies[] createVeggies() {Veggies veggies[] = {new Garlic(), new Onion(), new MushRoom(), new RedPepper()};return veggies;}@Overridepublic Clams createClam() {return new FreshClams();}@Overridepublic Pepperoni createPepperoni() {return new SlicePepproni();}}
 


package pizzaaf;/*** 芝加哥披萨原料工厂* @author wwj**/
 public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {@Overridepublic Dough createDough() {return new ThickCrustDough();}@Overridepublic Sauce createSauce() {return new plumTomatoSauce();}@Overridepublic Cheese createCheese() {return new Mozzarella();}@Overridepublic Veggies[] createVeggies() {Veggies veggies[] = {new BlackOlives(), new Spinach(), new EggPlant()};return veggies;}@Overridepublic Clams createClam() {return new FrozenClams();}@Overridepublic Pepperoni createPepperoni() {return new SlicedPepperoni();}}
 


所有原料接口,一系列产品族

package pizzaaf;public interface Cheese {@Overridepublic String toString();
 }
 

package pizzaaf;public interface Clams {@Overridepublic String toString();
 }
 

package pizzaaf;public interface Dough {@Overridepublic String toString();
 }
 

package pizzaaf;public interface Sauce {@Overridepublic String toString();
 }
 

package pizzaaf;public interface Veggies {@Overridepublic String toString();
 }
 

package pizzaaf;public interface Pepperoni {@Overridepublic 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";}
 }
 



关于工厂模式已经介绍完,蛮多内容的是吧。 什么时候用工厂方法和抽象方法呢? 来听听它们的告白: 抽象工厂:我是抽象工厂,当你需要创建产品家族和想让制造的相关产品集合起来时,你可以使用我。 工厂方法:我是工厂方法,我可以把你的客户代码从实例化的具体类中解耦。或者如果你目前还不知道将来需要实例化哪些具体类时,也可以用我。我的使用方式简单,只要把握继承成子类,并实现我的工厂方法就行了。

标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。