抽象工厂方法模式(Abstract Factory Pattern)
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
应用实例:汽车工厂生产轿车和卡车,轿车和卡车就是同类产品(都是汽车嘛,汽车内当然大多零件生产是相通的),通过抽象工厂,还可以复用许多代码。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。如示例中,增加一个MiniCar产品,改动较大,但是如果说增加一个五菱品牌(相当于产品等级,肯定比BMW级别低了很多吧),直接继承抽象类扩展即可。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序(因为接口相同,调用工厂的不同方法生产相应操作系统的程序,屏蔽底层操作影响,例如AppFactory.CreateLinuxApp,AppFactory.CreateWindowsApp)。
注意事项:产品族难扩展,产品等级易扩展。
抽象类:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DesignPattern.AbscractFactoryPattern 7 { 8 //这里使用抽象类是因为接口必须在子类实现方法,抽象类可以延迟到抽象子类去。 9 public abstract class AbstractCar 10 { 11 public abstract void Run(); 12 public abstract void BeBe(); 13 public abstract void GetBrand(); 14 } 15 16 public abstract class AbstractCarFactory 17 { 18 public static AbstractCarFactory GetInsance() 19 { 20 //这里应该去读取配置文件,由于是demo就直接赋值了。 21 string factoryName = "BMWCarFactory"; 22 23 AbstractCarFactory instance; 24 25 if (factoryName != "") 26 instance = (AbstractCarFactory)Assembly.Load("DesignPattern").CreateInstance("DesignPattern.AbscractFactoryPattern." + factoryName); 27 else 28 instance = null; 29 30 return instance; 31 } 32 public abstract AbstractCar CreateSaloonCar(); 33 public abstract AbstractCar CreateTruckCar(); 34 } 35 36 public abstract class AbstractSaloonCar : AbstractCar 37 { 38 public override void Run() 39 { 40 Console.WriteLine("我是轿车~~"); 41 } 42 43 public override void BeBe() 44 { 45 Console.WriteLine("嘀嘀嘀~!!!"); 46 } 47 } 48 49 public abstract class AbstractTruckCar : AbstractCar 50 { 51 public override void Run() 52 { 53 Console.WriteLine("我是大卡卡卡卡……"); 54 } 55 56 public override void BeBe() 57 { 58 Console.WriteLine("嘟嘟嘟嘟嘟!!!"); 59 } 60 } 61 }
Benz工厂
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DesignPattern.AbscractFactoryPattern 7 { 8 public class BenzCarFactory : AbstractCarFactory 9 { 10 public override AbstractCar CreateSaloonCar() 11 { 12 return new BenzSaloonCar(); 13 } 14 15 public override AbstractCar CreateTruckCar() 16 { 17 return new BenzTruckCar(); 18 } 19 } 20 21 public class BenzSaloonCar : AbstractSaloonCar 22 { 23 public override void GetBrand() 24 { 25 Console.WriteLine("我是奔驰轿车!!!"); 26 } 27 } 28 29 public class BenzTruckCar : AbstractTruckCar 30 { 31 public override void GetBrand() 32 { 33 Console.WriteLine("我是奔驰大卡!!!"); 34 } 35 } 36 }
BMW工厂
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DesignPattern.AbscractFactoryPattern 7 { 8 public class BMWCarFactory : AbstractCarFactory 9 { 10 public override AbstractCar CreateSaloonCar() 11 { 12 return new BMWSaloonCar(); 13 } 14 15 public override AbstractCar CreateTruckCar() 16 { 17 return new BMWTruckCar(); 18 } 19 } 20 21 public class BMWSaloonCar : AbstractSaloonCar 22 { 23 public override void GetBrand() 24 { 25 Console.WriteLine("我是宝马轿车!"); 26 } 27 } 28 29 public class BMWTruckCar : AbstractTruckCar 30 { 31 public override void GetBrand() 32 { 33 Console.WriteLine("我是宝马大卡!!!"); 34 } 35 } 36 }
模拟场景
这个月只生产Benz轿车。下个月生产卡车换个方法即可。下一年生产BMW换个工厂即可(修改配置文件)。
1 //与工厂模式最大区别就是一个产品族的问题,同样的产品拥有很多相同约束,这样就不用重复写代码。 2 //AbstractCarFactory BenzFactory = new BenzCarFactory();//这里使用反射完全解耦 3 AbstractCarFactory Factory = AbstractCarFactory.GetInsance(); 4 AbstractCar _saloonCar = Factory.CreateSaloonCar(); 5 _saloonCar.BeBe(); 6 _saloonCar.Run(); 7 _saloonCar.GetBrand();
我不怕千万人阻挡,只怕自己投降。