詳解C#的設計模式編程之抽象工廠模式的應用
這里首先以一個生活中抽象工廠的例子來實現(xiàn)一個抽象工廠,然后再給出抽象工廠的定義和UML圖來幫助大家更好地掌握抽象工廠模式,同時大家在理解的時候,可以對照抽象工廠生活中例子的實現(xiàn)和它的定義來加深抽象工廠的UML圖理解。抽象工廠模式比其它工廠模式更加抽象,抽象工廠模式適用與多個抽象類的情況下,通過工廠返回多個抽象類中你需要得到的具體子類實例。
抽象工廠模式比其它工廠模式更加抽象,抽象工廠模式適用與多個抽象類的情況下,通過工廠返回多個抽象類中你需要得到的具體子類實例。
舉例闡述抽象工廠模式:
假如中國對邪惡國家開戰(zhàn)。
中國裝備:炸彈類,坦克類,來消滅邪惡國家。
炸彈類:導彈,核彈;
坦克類:越野車,主站坦克;
戰(zhàn)略:
前期中國兵工廠生產:導彈,越野車,打擊邪惡國家。
后期中國兵工廠生產:核彈,主站坦克,毀滅邪惡國家。
類圖:
裝備類代碼:
#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客戶端代碼:(打仗) // 備戰(zhàn) class Make { //裝備 private Bomb bomb; private Tank tank; //制造加工 public Make(chinaFactory factory) { bomb = factory.CreateBomb(); tank = factory.CreateTank(); } //開始打仗 public void warStar() { //炸彈類爆炸 bomb.baozha(); //戰(zhàn)車類前進 tank.go(); } } public class start { public static void Main() { //大戰(zhàn)前期 chinaFactory qianqiMake = new qianqiFactory(); Make qianqi = new Make(qianqiMake); qianqi.warStar(); //點任意鍵,進行后期攻勢??! Console.ReadKey(); //大戰(zhàn)后期 chinaFactory houqiMake = new houqiFactory(); Make houqi = new Make(houqiMake); houqi.warStar(); Console.WriteLine("釣魚島是中國的,神圣不可侵犯!小邪惡國家,滾開??!"); Console.ReadLine(); } }
抽象工廠模式的定義和類圖
抽象工廠允許客戶使用抽象的接口來創(chuàng)建一組相關產品,而不需要知道或關心實際生產出的具體產品是什么。這樣客戶就可以從具體產品中被解耦。下面通過抽象工模式的類圖來了解各個類中之間的關系:
抽象工廠的分析
抽象工廠模式將具體產品的創(chuàng)建延遲到具體工廠的子類中,這樣將對象的創(chuàng)建封裝起來,可以減少客戶端與具體產品類之間的依賴,從而使系統(tǒng)耦合度低,這樣更有利于后期的維護和擴展,這真是抽象工廠模式的優(yōu)點所在,然后抽象模式同時也存在不足的地方。下面就具體看下抽象工廠的缺點(缺點其實在前面的介紹中以已經涉及了):
抽象工廠模式很難支持新種類產品的變化。這是因為抽象工廠接口中已經確定了可以被創(chuàng)建的產品集合,如果需要添加新產品,此時就必須去修改抽象工廠的接口,這樣就涉及到抽象工廠類的以及所有子類的改變,這樣也就違背了“開發(fā)——封閉”原則。
知道了抽象工廠的優(yōu)缺點之后,也就能很好地把握什么情況下考慮使用抽象工廠模式了,下面就具體看看使用抽象工廠模式的系統(tǒng)應該符合那幾個前提:
一個系統(tǒng)不要求依賴產品類實例如何被創(chuàng)建、組合和表達的表達,這點也是所有工廠模式應用的前提。
這個系統(tǒng)有多個系列產品,而系統(tǒng)中只消費其中某一系列產品
系統(tǒng)要求提供一個產品類的庫,所有產品以同樣的接口出現(xiàn),客戶端不需要依賴具體實現(xiàn)。
.NET中抽象工廠模式實現(xiàn)
抽象工廠模式在實際中的應用也是相當頻繁的,然而在我們.NET類庫中也存在應用抽象工廠模式的類,這個類就是System.Data.Common.DbProviderFactory,這個類位于System.Data.dll程序集中,該類扮演抽象工廠模式中抽象工廠的角色,我們可以用reflector反編譯工具查看該類的實現(xiàn):
/// 扮演抽象工廠的角色 /// 創(chuàng)建連接數(shù)據(jù)庫時所需要的對象集合, /// 這個對象集合包括有 DbConnection對象(這個是抽象產品類,如絕味例子中的YaBo類)、DbCommand類、DbDataAdapter類,針對不同的具體工廠都需要實現(xiàn)該抽象類中方法, public abstract class DbProviderFactory { // 提供了創(chuàng)建具體產品的接口方法 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類是一個抽象工廠類,該類提供了創(chuàng)建數(shù)據(jù)庫連接時所需要的對象集合的接口,實際創(chuàng)建的工作在其子類工廠中進行,微軟使用的是SQL Server數(shù)據(jù)庫,因此提供了連接SQL Server數(shù)據(jù)的具體工廠實現(xiàn),具體代碼可以用反編譯工具查看,具體代碼如下: /// 扮演著具體工廠的角色,用來創(chuàng)建連接SQL Server數(shù)據(jù)所需要的對象 public sealed class SqlClientFactory : DbProviderFactory, IServiceProvider { // Fields public static readonly SqlClientFactory Instance = new SqlClientFactory(); // 構造函數(shù) private SqlClientFactory() { } // 重寫抽象工廠中的方法 public override DbCommand CreateCommand() { // 創(chuàng)建具體產品 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); } }
因為微軟只給出了連接SQL Server的具體工廠的實現(xiàn),我們也可以自定義連接Oracle、MySql的具體工廠的實現(xiàn)。
您可能感興趣的文章
- 01-10C#通過反射獲取當前工程中所有窗體并打開的方法
- 01-10關于ASP網頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#停止線程的方法
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新聞效果的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已安裝軟件變化的方法
- 01-10C#實現(xiàn)多線程下載文件的方法


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關于ASP網頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10C#中split用法實例總結
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery