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


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


