动机:在软件系统中,经常面临着“系列相互依赖的对象”的创建工作:同时,由于需求的变化,往往存在更多系列对象 的创建工作;如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?
意图:提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
适用性:
- 一个系统要独立于它的产品的创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
- 当你提供一个产品类库,而只想显示它们的接口而不是实现时。
UML图:
示例代码:游戏场景中AbstractFactory模式的应用
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace AbstractFactory 7 { 8 #region 一系列对象的抽象类定义 9 /// <summary> 10 /// 路(抽象类) 11 /// </summary> 12 public abstract class Road 13 { 14 15 } 16 17 /// <summary> 18 /// 房屋(抽象类) 19 /// </summary> 20 public abstract class Building 21 { 22 23 } 24 25 /// <summary> 26 /// 隧道(抽象类) 27 /// </summary> 28 public abstract class Tunnel 29 { 30 31 } 32 /// <summary> 33 /// 丛林(抽象类) 34 /// </summary> 35 public abstract class Jungle 36 { 37 38 } 39 #endregion 40 41 #region 一系列具体实例对象类的定义 42 43 #region 现代风格的一系列对象 44 /// <summary> 45 /// 现代风格的路 46 /// </summary> 47 public class ModernRoad:Road 48 { 49 50 } 51 52 /// <summary> 53 /// 现代风格的房屋 54 /// </summary> 55 public class ModernBuilding:Building 56 { 57 58 } 59 60 /// <summary> 61 /// 现代风格的隧道 62 /// </summary> 63 public class ModernTunnel:Tunnel 64 { 65 66 } 67 /// <summary> 68 /// 现代风格的丛林 69 /// </summary> 70 public class ModernJungle:Jungle 71 { 72 73 } 74 #endregion 75 76 #region 古代风格的一系列类 77 /// <summary> 78 /// 古老风格的路 79 /// </summary> 80 public class AncientRoad : Road 81 { 82 83 } 84 85 /// <summary> 86 /// 古老风格的房屋 87 /// </summary> 88 public class AncientBuilding : Building 89 { 90 91 } 92 93 /// <summary> 94 /// 古老风格的隧道 95 /// </summary> 96 public class AncientTunnel : Tunnel 97 { 98 99 } 100 /// <summary> 101 /// 古老风格的丛林 102 /// </summary> 103 public class AncientJungle : Jungle 104 { 105 106 } 107 #endregion 108 109 #endregion 110 111 /// <summary> 112 /// 场景设施抽象创建工厂类 113 /// </summary> 114 public abstract class FacilitiesFactory 115 { 116 public abstract Road CreateRoad(); 117 public abstract Building CreateBuilding(); 118 public abstract Tunnel CreateTunnel(); 119 public abstract Jungle CreateJungle(); 120 } 121 122 /// <summary> 123 /// 现代风格的对象创建工厂类 124 /// </summary> 125 public class ModernFacilitiesFactory : FacilitiesFactory 126 { 127 128 public override Road CreateRoad() 129 { 130 return new ModernRoad(); 131 } 132 133 public override Building CreateBuilding() 134 { 135 return new ModernBuilding(); 136 } 137 138 public override Tunnel CreateTunnel() 139 { 140 return new ModernTunnel(); 141 } 142 143 public override Jungle CreateJungle() 144 { 145 return new ModernJungle(); 146 } 147 } 148 149 /// <summary> 150 /// 古代风格的对象创建工厂类 151 /// </summary> 152 public class AncientFacilitiesFactory : FacilitiesFactory 153 { 154 155 public override Road CreateRoad() 156 { 157 return new AncientRoad(); 158 } 159 160 public override Building CreateBuilding() 161 { 162 return new AncientBuilding(); 163 } 164 165 public override Tunnel CreateTunnel() 166 { 167 return new AncientTunnel(); 168 } 169 170 public override Jungle CreateJungle() 171 { 172 return new AncientJungle(); 173 } 174 }
客户程序实现代码:
1 /// <summary> 2 /// 假设此类为客户程序 3 /// </summary> 4 public class GameManager 5 { 6 /*** 7 * 当需要增加另一种风格的场景时,只需要继承对应的抽象类实现此风格下的实例对象类和具体工厂类即可 8 * 而客户程序无需改动或改动甚少,这既是这种设计模式的优势 9 * ***/ 10 FacilitiesFactory _facilitiesfactory; 11 Road road; 12 Building building; 13 Tunnel tunnel; 14 Jungle jungle; 15 public GameManager(FacilitiesFactory facilitiesfactory ) 16 { 17 this._facilitiesfactory = facilitiesfactory; 18 } 19 20 /// <summary> 21 /// 创建游戏场景 22 /// </summary> 23 public void BuildGameFacilities() 24 { 25 road = _facilitiesfactory.CreateRoad(); 26 building = _facilitiesfactory.CreateBuilding(); 27 tunnel = _facilitiesfactory.CreateTunnel(); 28 jungle = _facilitiesfactory.CreateJungle(); 29 } 30 31 /// <summary> 32 /// 开始游戏 33 /// </summary> 34 public void Play() 35 { 36 37 } 38 } 39 40 } 41 42 public class App 43 { 44 public static void Main() 45 { 46 FacilitiesFactory ff = new ModernFacilitiesFactory(); 47 GameManager game = new GameManager(ff); 48 game.BuildGameFacilities(); 49 game.Play(); 50 } 51 }
注:本示例代码是本人学习Webcast C#面向对象设计模式纵横谈系列讲座视频时,跟着李建忠老师一步一步的编写的,在此奉献出来,仅供大家参考