程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 詳解C#的設計模式編程之抽象工廠模式的應用

詳解C#的設計模式編程之抽象工廠模式的應用

編輯:關於C語言

這裡首先以一個生活中抽象工廠的例子來實現一個抽象工廠,然後再給出抽象工廠的定義和UML圖來幫助大家更好地掌握抽象工廠模式,同時大家在理解的時候,可以對照抽象工廠生活中例子的實現和它的定義來加深抽象工廠的UML圖理解。抽象工廠模式比其它工廠模式更加抽象,抽象工廠模式適用與多個抽象類的情況下,通過工廠返回多個抽象類中你需要得到的具體子類實例。

抽象工廠模式比其它工廠模式更加抽象,抽象工廠模式適用與多個抽象類的情況下,通過工廠返回多個抽象類中你需要得到的具體子類實例。

舉例闡述抽象工廠模式:
假如中國對邪惡國家開戰。

中國裝備:炸彈類,坦克類,來消滅邪惡國家。

炸彈類:導彈,核彈;

坦克類:越野車,主站坦克;

戰略:

前期中國兵工廠生產:導彈,越野車,打擊邪惡國家。

後期中國兵工廠生產:核彈,主站坦克,毀滅邪惡國家。

類圖:

2016217144844885.png (1091×595)

裝備類代碼:

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 #region 炸彈系列 abstract class Bomb { abstract public void baozha(); } /// <summary> /// 導彈 /// </summary> class daodanBomb :Bomb { public override void baozha() { Console.WriteLine("我是一顆中國造導彈,來轟炸不老實的小邪惡國家!"); } } /// <summary> /// 核彈 /// </summary> class hedanBomb : Bomb { public override void baozha() { Console.WriteLine("我是一顆中國造核彈,來轟炸不老實的小邪惡國家!"); } } #endregion #region 坦克系列 abstract class Tank { abstract public void go(); } /// <summary> /// 越野車 /// </summary> class yueyeTank : Tank { public override void go() { Console.WriteLine("我是一顆中國造越野車,來踏平不老實的小邪惡國家!"); } } /// <summary> /// 主站坦克 /// </summary> class zhuzhanTank : Tank { public override void go() { Console.WriteLine("我是一顆中國造主站坦克,來踏平不老實的小邪惡國家!"); } } #endregion工廠類代碼 #region 中國兵工廠 abstract class chinaFactory { //裝甲車制造車間 public abstract Tank CreateTank(); //炸彈知道車間 public abstract Bomb CreateBomb(); } //兵工廠前期制造 class qianqiFactory : chinaFactory { public override Bomb CreateBomb() { //導彈 return new daodanBomb(); } public override Tank CreateTank() { //越野車 return new yueyeTank(); } } //兵工廠後期制造 class houqiFactory : chinaFactory { public override Bomb CreateBomb() { //核彈 return new hedanBomb(); } public override Tank CreateTank() { //主站坦克 return new zhuzhanTank(); } } #endregion客戶端代碼:(打仗) // 備戰 class Make { //裝備 private Bomb bomb; private Tank tank; //制造加工 public Make(chinaFactory factory) { bomb = factory.CreateBomb(); tank = factory.CreateTank(); } //開始打仗 public void warStar() { //炸彈類爆炸 bomb.baozha(); //戰車類前進 tank.go(); } } public class start { public static void Main() { //大戰前期 chinaFactory qianqiMake = new qianqiFactory(); Make qianqi = new Make(qianqiMake); qianqi.warStar(); //點任意鍵,進行後期攻勢!! Console.ReadKey(); //大戰後期 chinaFactory houqiMake = new houqiFactory(); Make houqi = new Make(houqiMake); houqi.warStar(); Console.WriteLine("釣魚島是中國的,神聖不可侵犯!小邪惡國家,滾開!!"); Console.ReadLine(); } }


抽象工廠模式的定義和類圖

抽象工廠允許客戶使用抽象的接口來創建一組相關產品,而不需要知道或關心實際生產出的具體產品是什麼。這樣客戶就可以從具體產品中被解耦。下面通過抽象工模式的類圖來了解各個類中之間的關系:

2016217144927859.png (633×457)

抽象工廠的分析
抽象工廠模式將具體產品的創建延遲到具體工廠的子類中,這樣將對象的創建封裝起來,可以減少客戶端與具體產品類之間的依賴,從而使系統耦合度低,這樣更有利於後期的維護和擴展,這真是抽象工廠模式的優點所在,然後抽象模式同時也存在不足的地方。下面就具體看下抽象工廠的缺點(缺點其實在前面的介紹中以已經涉及了):

抽象工廠模式很難支持新種類產品的變化。這是因為抽象工廠接口中已經確定了可以被創建的產品集合,如果需要添加新產品,此時就必須去修改抽象工廠的接口,這樣就涉及到抽象工廠類的以及所有子類的改變,這樣也就違背了“開發——封閉”原則。

知道了抽象工廠的優缺點之後,也就能很好地把握什麼情況下考慮使用抽象工廠模式了,下面就具體看看使用抽象工廠模式的系統應該符合那幾個前提:

一個系統不要求依賴產品類實例如何被創建、組合和表達的表達,這點也是所有工廠模式應用的前提。
這個系統有多個系列產品,而系統中只消費其中某一系列產品
系統要求提供一個產品類的庫,所有產品以同樣的接口出現,客戶端不需要依賴具體實現。


.Net中抽象工廠模式實現
抽象工廠模式在實際中的應用也是相當頻繁的,然而在我們.Net類庫中也存在應用抽象工廠模式的類,這個類就是System.Data.Common.DbProviderFactory,這個類位於System.Data.dll程序集中,該類扮演抽象工廠模式中抽象工廠的角色,我們可以用reflector反編譯工具查看該類的實現:

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 /// 扮演抽象工廠的角色 /// 創建連接數據庫時所需要的對象集合, /// 這個對象集合包括有 DbConnection對象(這個是抽象產品類,如絕味例子中的YaBo類)、DbCommand類、DbDataAdapter類,針對不同的具體工廠都需要實現該抽象類中方法, public abstract class DbProviderFactory { // 提供了創建具體產品的接口方法 protected DbProviderFactory(); public virtual DbCommand CreateCommand(); public virtual DbCommandBuilder CreateCommandBuilder(); public virtual DbConnection CreateConnection(); public virtual DbConnectionStringBuilder CreateConnectionStringBuilder(); public virtual DbDataAdapter CreateDataAdapter(); public virtual DbDataSourceEnumerator CreateDataSourceEnumerator(); public virtual DbParameter CreateParameter(); public virtual CodeAccessPermission CreatePermission(PermissionState state); } DbProviderFactory類是一個抽象工廠類,該類提供了創建數據庫連接時所需要的對象集合的接口,實際創建的工作在其子類工廠中進行,微軟使用的是SQL Server數據庫,因此提供了連接SQL Server數據的具體工廠實現,具體代碼可以用反編譯工具查看,具體代碼如下: /// 扮演著具體工廠的角色,用來創建連接SQL Server數據所需要的對象 public sealed class SqlClIEntFactory : DbProviderFactory, IServiceProvider { // FIElds public static readonly SqlClIEntFactory Instance = new SqlClIEntFactory(); // 構造函數 private SqlClIEntFactory() { } // 重寫抽象工廠中的方法 public override DbCommand CreateCommand() { // 創建具體產品 return new SqlCommand(); } public override DbCommandBuilder CreateCommandBuilder() { return new SqlCommandBuilder(); } public override DbConnection CreateConnection() { return new SqlConnection(); } public override DbConnectionStringBuilder CreateConnectionStringBuilder() { return new SqlConnectionStringBuilder(); } public override DbDataAdapter CreateDataAdapter() { return new SqlDataAdapter(); } public override DbDataSourceEnumerator CreateDataSourceEnumerator() { return SqlDataSourceEnumerator.Instance; } public override DbParameter CreateParameter() { return new SqlParameter(); } public override CodeAccessPermission CreatePermission(PermissionState state) { return new SqlClIEntPermission(state); } }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved