抽象工厂方法模式(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();

 

posted @ 2016-09-01 16:42  leestar54  阅读(215)  评论(0编辑  收藏  举报