深入浅出设计模式-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");
}
六:简单工厂和抽象工厂总结
所有的工厂都是用来封装对象的创建。
简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。
工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。
抽象工厂使用对象组合:对象的创建被实现在工厂接口锁暴露出来的方法中。
所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。
工厂方法允许类将实例化推迟到子类进行。
抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。
依赖倒置原则指导我们避免依赖具体类型,而要尽量依赖抽象。
工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体编程。