设计模式-创建型-抽象工厂模式

前一章节,我们介绍了 简单工厂模式以及工厂方法模式 ,但是这两种模式都存在一定的局限性,只能生产某一类型下的某一种产品,如果需求变更,同类型下出现了不同的产品,比如芝士披萨不仅有口味上的不同,同时存在外观上的不同。这种时候,工厂模式显然不再满足要求,该怎么办呢? 于是我们想到 DIP原则 ,它不正是为了解决这种情况而存在的吗?接下来我们来介绍下抽象工厂模式:

1、抽象工厂模式定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类。

2、抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。

3、从设计层面来说,抽象工厂模式就是对简单工厂模式的改进(即进一步抽象化)

4、将工厂抽象成两层,抽象工厂和具体的实现工厂。

还是拿pizza订购举例,我们定义一个抽象工厂AbsFactory,由子类工厂实现该抽象工厂;订购披萨OrderPizza依赖抽象,不依赖具体的实现。

 


  1 internal class Program
  2 {
  3     private static void Main(string[] args)
  4     {
  5         new OrderPizza(new BJFactory());
  6     }
  7 }
  8 
  9 internal class OrderPizza
 10 {
 11     private AbsFactory factory;
 12 
 13     public OrderPizza(AbsFactory factory)
 14     {
 15         setFactory(factory);
 16         Order();
 17     }
 18 
 19     private void setFactory(AbsFactory factory)
 20     {
 21         this.factory = factory;
 22     }
 23 
 24     private void Order()
 25     {
 26         Pizza pizza = null;
 27         string orderType = "";
 28         do
 29         {
 30             Console.Write("请输入订购类型:");
 31             orderType = Console.ReadLine();
 32             pizza = this.factory.createPizza(orderType);
 33             if (pizza == null)
 34             {
 35                 Console.WriteLine("订购失败");
 36                 break;
 37             }
 38             //开始制作
 39             pizza.prepare();
 40             pizza.bake();
 41             pizza.cut();
 42             pizza.box();
 43         } while (true);
 44     }
 45 }
 46 
 47 internal interface AbsFactory
 48 {
 49     Pizza createPizza(string orderType);
 50 }
 51 
 52 internal class BJFactory : AbsFactory
 53 {
 54     public Pizza createPizza(string orderType)
 55     {
 56         Pizza pizza = null;
 57         if (orderType == "cheese")
 58         {
 59             pizza = new BJCheesePizza();
 60             pizza.setName("北京芝士披萨");
 61         }
 62         else if (orderType == "greek")
 63         {
 64             pizza = new BJGreekPizza();
 65             pizza.setName("北京希腊披萨");
 66         }
 67         return pizza;
 68     }
 69 }
 70 
 71 internal class LDFactory : AbsFactory
 72 {
 73     public Pizza createPizza(string orderType)
 74     {
 75         Pizza pizza = null;
 76         if (orderType == "cheese")
 77         {
 78             pizza = new LDCheesePizza();
 79             pizza.setName("伦敦芝士披萨");
 80         }
 81         else if (orderType == "greek")
 82         {
 83             pizza = new LDGreekPizza();
 84             pizza.setName("伦敦希腊披萨");
 85         }
 86         return pizza;
 87     }
 88 }
 89 
 90 internal abstract class Pizza
 91 {
 92     private string name;
 93 
 94     public abstract void prepare();
 95 
 96     public void bake()
 97     {
 98         Console.WriteLine($"{this.name} 烘培");
 99     }
100 
101     public void cut()
102     {
103         Console.WriteLine($"{this.name} 修剪");
104     }
105 
106     public void box()
107     {
108         Console.WriteLine($"{this.name} 打包");
109     }
110 
111     public void setName(string name)
112     {
113         this.name = name;
114     }
115 }
116 
117 internal class BJCheesePizza : Pizza
118 {
119     public override void prepare()
120     {
121         Console.WriteLine("北京的芝士披萨准备中");
122     }
123 }
124 
125 internal class BJGreekPizza : Pizza
126 {
127     public override void prepare()
128     {
129         Console.WriteLine("北京的希腊披萨准备中");
130     }
131 }
132 
133 internal class LDCheesePizza : Pizza
134 {
135     public override void prepare()
136     {
137         Console.WriteLine("伦敦的芝士披萨准备中");
138     }
139 }
140 
141 internal class LDGreekPizza : Pizza
142 {
143     public override void prepare()
144     {
145         Console.WriteLine("伦敦的希腊披萨准备中");
146     }
147 }

view code

读过一些博主的博文以及评论,有一些理解还是蛮到位的:

1、抽象工厂比工厂方法复杂的多,它们的目的不同。工厂方法意在延迟加载,而抽象方法意在高内聚低耦合。

2、工厂方法模式的具体工厂类只能创建一个具体具体产品类的实例,而抽象工厂可以创建多个。

参考: https://www.runoob.com/design-pattern/abstract-factory-pattern.html