前一章节,我们介绍了简单工厂模式以及工厂方法模式,但是这两种模式都存在一定的局限性,只能生产某一类型下的某一种产品,如果需求变更,同类型下出现了不同的产品,比如芝士披萨不仅有口味上的不同,同时存在外观上的不同。这种时候,工厂模式显然不再满足要求,该怎么办呢?于是我们想到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 : Pizza118 {119 public override void prepare()120 {121 Console.WriteLine("北京的芝士披萨准备中");122 }123 }124 125 internal class BJGreekPizza : Pizza126 {127 public override void prepare()128 {129 Console.WriteLine("北京的希腊披萨准备中");130 }131 }132 133 internal class LDCheesePizza : Pizza134 {135 public override void prepare()136 {137 Console.WriteLine("伦敦的芝士披萨准备中");138 }139 }140 141 internal class LDGreekPizza : Pizza142 {143 public override void prepare()144 {145 Console.WriteLine("伦敦的希腊披萨准备中");146 }147 }
读过一些博主的博文以及评论,有一些理解还是蛮到位的:
1、抽象工厂比工厂方法复杂的多,它们的目的不同。工厂方法意在延迟加载,而抽象方法意在高内聚低耦合。
2、工厂方法模式的具体工厂类只能创建一个具体具体产品类的实例,而抽象工厂可以创建多个。
参考:https://www.runoob.com/design-pattern/abstract-factory-pattern.html
原文链接:http://www.cnblogs.com/az4215/p/11518442.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728