深入浅出设计模式-004:工厂模式(Factory Pattern)
一:工厂模式 定义了一个创建对象的接口,但由子类决定实例化的类是哪一个。工厂方法把类实例化推迟到子类。 将创建对象的代码集中在一个对象或方法中。可以避免代码的重复,并且更方便以后的维护。这也意味着客户在实例化对象时,只会依赖接口而不是具体类。 注意:对象的创建时现实的,如果不创建任何对象,就无法创建任何程序了。
二:abstract Product factoryMethod(String type) 工厂方法用来处理对象的创建,并将这样的行为封装在子类中。 工厂方法是抽象的,所以依赖子类来处理对象的创建 工厂方法必须返回一个产品,超类中定义的方法,通常使用到工厂方法的返回值 工厂方法将客户和实际创建具体产品的代码分隔开来。
三:依赖倒置原则:要依赖抽象,不要依赖具体类 不能让高层组件依赖底层组件。而且不管高层或底层组件,两者都应该依赖于抽象。 变量不可以持有具体类的引用:如果使用NEW,就会持有具体类的引用。可以使用工厂方法避开。 不要让类派生自具体类:如果派生自具体类,你就会依赖具体类。 不要覆盖基类中已实现的方法:如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象。基类已实现的方法应该由所有子类共享。
四:PizzaStore是高层组件,而Pizza的实现是底层组件。高层组件依赖这些具体比萨类。 public abstract class Pizza{ public String name; public String dough; public String sauce; public ArrayList toppings = new ArrayList();
public void prepare(){ Console.WriteLine("prepare"); } public void bake(){ Console.WriteLine("bake"); } public void cut(){ Console.WriteLine("cut"); } public void box(){ Console.WriteLine("box"); } public String getName(){ return name; } } public class NYStyleCheesePizza : Pizza{ public NYStyleCheesePizza(){ name = "NYStyleCheesePizza name"; dough = "NYStyleCheesePizza dough"; sauce = "NYStyleCheesePizza sauce"; toppings.Add("NYStyleCheesePizza"); } } public class ChicagoStyleCheesePizza : Pizza{ public ChicagoStyleCheesePizza(){ name = "ChicagoStyleCheesePizza name"; dough = "ChicagoStyleCheesePizza dough"; sauce = "ChicagoStyleCheesePizza sauce"; toppings.Add("ChicagoStyleCheesePizza"); } public void cut(){ Console.WriteLine("ChicagoStyleCheesePizza cut"); } }
public abstract class PizzaStore{ //创建者类,它定义了一个抽象的工厂方法,让子类实现此方法制造产品 public abstract Pizza createPizza(String type); public Pizza orderPizza(String type){ Pizza pizza; pizza = createPizza(type);
pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box();
return pizza; } } public class NYStyleCheesePizzaStore : PizzaStore{ public override Pizza createPizza(string type){ if (type.Equals("cheese")){ return new NYStyleCheesePizza(); } else{ return null; } } } public class ChicagoStyleCheesePizzaStore : PizzaStore{ public override Pizza createPizza(string type){ if (type.Equals("chicago")){ return new ChicagoStyleCheesePizza(); } else{ return null; } } } static void Main(string[] args) { PizzaStore cheeseStore = new NYStyleCheesePizzaStore(); PizzaStore chicageStore = new ChicagoStyleCheesePizzaStore();
Pizza pizza = cheeseStore.orderPizza("cheese"); Console.WriteLine(pizza.getName());
pizza = chicageStore.orderPizza("chicago"); Console.WriteLine(pizza.getName()); }
五:抽象工厂模式 提供一个接口,用于创建相关或依赖对象的家族,而不用明确执行具体类
//各种原料 public interface Dough{ string toString(); } public class ThickCrustDough : Dough{ public string toString(){ return "ThickCrust Dough"; } } public class ThinCrustDough : Dough{ public string toString(){ return "ThinCrust Dough"; } }
public interface Sauce{ string toString(); } public class MarinaraSauce : Sauce{ public string toString(){ return "Marinara Sauce"; } } public class PlumTomatoSauce : Sauce{ public string toString(){ return "PlumTomato Sauce"; } }
public interface Cheese{ string toString(); } public class Mozzerella : Cheese{ public string toString(){ return "Mozzerella Cheese"; } } public class ReggianoCheese : Cheese{ public string toString(){ return "ReggianoCheese Cheese"; } }
public interface Veggies{ string toString(); } public class RedPepper : Veggies{ public string toString(){ return "RedPepper Veggies"; } } public class Spinach : Veggies{ public string toString(){ return "Spinach Veggies"; } } public class BlackOlives : Veggies{ public string toString(){ return "BlackOlives Veggies"; } } public class EggPlant : Veggies{ public string toString(){ return "EggPlant Veggies"; } } public class Garlic : Veggies{ public string toString(){ return "Garlic Veggies"; } } public class Mushroom : Veggies{ public string toString(){ return "Mushroom Veggies"; } } public class Onion : Veggies{ public string toString(){ return "Onion Veggies"; } }
public interface Pepperoni{ string toString(); } public class SlicedPepperoni : Pepperoni{ public string toString(){ return "Sliced Pepperoni"; } }
public interface Clams{ string toString(); } public class FreshClams : Clams{ public string toString(){ return "FreshClams Clams"; } } public class FrozenClams : Clams{ public string toString(){ return "FrozenClams Clams"; } }
//原料供应商 public interface PizzaIngredientFactory{ Dough createDough(); Sauce createSauce(); Cheese createCheese(); Veggies[] createVeggies(); Pepperoni createPepperoni(); Clams createClams(); } public class NYPizzaIngredientFactory : PizzaIngredientFactory{ public Dough createDough(){ return new ThinCrustDough(); } public Sauce createSauce(){ return new MarinaraSauce(); } public Cheese createCheese(){ return new ReggianoCheese(); } public Veggies[] createVeggies(){ Veggies[] veggies = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() }; return veggies; } public Pepperoni createPepperoni(){ return new SlicedPepperoni(); } public Clams createClams(){ return new FreshClams(); } } public class ChicagoPizzaIngredientFactory : PizzaIngredientFactory{ public Dough createDough(){ return new ThickCrustDough(); } public Sauce createSauce(){ return new PlumTomatoSauce(); } public Cheese createCheese(){ return new Mozzerella(); } public Veggies[] createVeggies(){ Veggies[] veggies = { new BlackOlives(), new Spinach(), new EggPlant() }; return veggies; } public Pepperoni createPepperoni(){ return new SlicedPepperoni(); } public Clams createClams(){ return new FrozenClams(); } }
//产品,制作时,用到了哪个地方的哪些原材料 public abstract class Pizza{ public String name; public Dough dough; public Sauce sauce; public Veggies[] veggies; public Cheese cheese; public Pepperoni pepperoni; public Clams clam;
//各种PIZZA制作时选用的原材料不一样 public abstract void prepare(); public void bake(){ Console.WriteLine("bake"); } public void cut(){ Console.WriteLine("cut"); } public void box(){ Console.WriteLine("box"); } public String getName(){ return name; } } public class CheesePizza : Pizza{ PizzaIngredientFactory ingredientFactory; //选用了哪个地方的原材料 public CheesePizza(PizzaIngredientFactory ingredientFactory){ this.ingredientFactory = ingredientFactory; } public override void prepare(){ dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); } } public class ClamPizza : Pizza{ PizzaIngredientFactory ingredientFactory; public ClamPizza(PizzaIngredientFactory ingredientFactory){ this.ingredientFactory = ingredientFactory; } public override void prepare(){ dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); clam = ingredientFactory.createClams(); } }
public abstract class PizzaStore{ //创建者类,它定义了一个抽象的工厂方法,让子类实现此方法制造产品 public abstract Pizza createPizza(String type); public Pizza orderPizza(String type){ Pizza pizza; pizza = createPizza(type);
pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box();
return pizza; } } public class NYPizzaStore : PizzaStore{ public override Pizza createPizza(string type){ Pizza pizza = null; PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory(); if (type.Equals("cheese")){ pizza = new CheesePizza(ingredientFactory); } else if (type.Equals("clam")){ pizza = new ClamPizza(ingredientFactory); } return pizza; } } public class ChicagoPizzaStore : PizzaStore{ public override Pizza createPizza(string type){ Pizza pizza = null; PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory(); if (type.Equals("cheese")){ pizza = new CheesePizza(ingredientFactory); } else if (type.Equals("clam")){ pizza = new ClamPizza(ingredientFactory); } return pizza; } }
static void Main(string[] args) { PizzaStore nyStore = new NYPizzaStore(); Pizza pizza = nyStore.orderPizza("cheese");
PizzaStore nyStore = new NYPizzaStore(); Pizza pizza = nyStore.OrderPizza("clam");
PizzaStore.PizzaStore nyStore = new NYPizzaStore(); Pizza pizza = nyStore.OrderPizza("pepperoni");
PizzaStore chicagoStore = new ChicagoPizzaStore(); Pizza pizza = chicagoStore.OrderPizza("cheese");
PizzaStore.PizzaStore chicagoStore = new ChicagoPizzaStore(); Pizza pizza = chicagoStore.OrderPizza("clam");
PizzaStore chicagoStore = new ChicagoPizzaStore(); Pizza pizza = chicagoStore.OrderPizza("pepperoni"); }
六:简单工厂和抽象工厂总结 所有的工厂都是用来封装对象的创建。 简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。 工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。 抽象工厂使用对象组合:对象的创建被实现在工厂接口锁暴露出来的方法中。 所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。 工厂方法允许类将实例化推迟到子类进行。 抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。 依赖倒置原则指导我们避免依赖具体类型,而要尽量依赖抽象。 工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体编程。