徐 宏
(太原城市職業(yè)技術(shù)學(xué)院,山西 太原 030027)
利用案例教學(xué)法由淺入深地講解抽象工廠模式
徐 宏
(太原城市職業(yè)技術(shù)學(xué)院,山西 太原 030027)
文章主要闡述了抽象工廠模式,通過(guò)利用案例教學(xué)法進(jìn)行講解,讓學(xué)員徹底理解并會(huì)使用抽象工廠設(shè)計(jì)模式。
抽象工廠模式;案例教學(xué)法;講解
抽象工廠模式是所有形態(tài)的工廠模式中最為抽象和最具一般性的一種形態(tài)。抽象工廠模式是指當(dāng)有多個(gè)抽象角色時(shí),使用的一種工廠模式。抽象工廠模式可以向客戶(hù)端提供一個(gè)接口,使客戶(hù)端在不必指定產(chǎn)品的具體的情況下,創(chuàng)建多個(gè)產(chǎn)品族中的產(chǎn)品對(duì)象。根據(jù)LSP原則,任何接受父類(lèi)型的地方,都應(yīng)當(dāng)能夠接受子類(lèi)型。因此,實(shí)際上系統(tǒng)所需要的,僅僅是類(lèi)型與這些抽象產(chǎn)品角色相同的一些實(shí)例,而不是這些抽象產(chǎn)品的實(shí)例。換言之,也就是這些抽象產(chǎn)品的具體子類(lèi)的實(shí)例。工廠類(lèi)負(fù)責(zé)創(chuàng)建抽象產(chǎn)品的具體子類(lèi)的實(shí)例。
學(xué)生在利用該設(shè)計(jì)模式開(kāi)發(fā)項(xiàng)目的時(shí)候,往往只是機(jī)械地照搬教師的源代碼,并沒(méi)有真正理解抽象工廠的含義。那么如何講解好這個(gè)知識(shí)點(diǎn)呢?在實(shí)際的授課過(guò)程中,筆者總結(jié)了講解這個(gè)難點(diǎn)的方法和技巧,總結(jié)出來(lái)與大家共享。
這里,筆者采用了案例教學(xué)法,層層深入,大約需要3個(gè)階段把這個(gè)難點(diǎn)講解完成。具體的思路是:首先,讓學(xué)員明白引入接口的原因;其次,講解使用簡(jiǎn)單工廠的便利;最后,講解使用抽象工廠是錦上添花。
文章所使用的案例是一個(gè)用VS2008開(kāi)發(fā)的用戶(hù)登錄程序。
第一階段:講解接口的引入,為什么要使用接口呢?這里需要跟學(xué)生說(shuō)明,目前的軟件產(chǎn)品大部分都會(huì)和數(shù)據(jù)庫(kù)進(jìn)行交互,但每個(gè)公司或企業(yè)不可能使用同樣的數(shù)據(jù)庫(kù)。例如,一個(gè)工資管理系統(tǒng),大公司可能使用SQLServer,而小公司可能使用Access就夠用了,那么如何讓一套程序既可使用SQLServer,又可使用Access作為數(shù)據(jù)庫(kù)呢?答案是我們?cè)跀?shù)據(jù)訪問(wèn)層使用統(tǒng)一的接口,讓訪問(wèn)SQLServer和Access的類(lèi)都實(shí)現(xiàn)這個(gè)接口,然后通過(guò)接口調(diào)用具體的實(shí)現(xiàn)。
具體的演示方法是在用戶(hù)登錄系統(tǒng)的基礎(chǔ)上點(diǎn)擊DAL層的類(lèi),右鍵選擇重構(gòu),選擇提取接口,這樣一個(gè)接口就出現(xiàn)了,見(jiàn)圖1。
這里為了更加的規(guī)范,新建一個(gè)接口層的類(lèi)庫(kù)IDAL,將這個(gè)接口移到這個(gè)類(lèi)庫(kù)IDAL中,見(jiàn)圖2。
接口建立以后,為了可以使用Access庫(kù),添加新的數(shù)據(jù)層AccessDAL,再添加一個(gè)AccessUserDAL類(lèi)并實(shí)現(xiàn)剛才創(chuàng)建的接口。最后修改BLL層的調(diào)用方式為接口調(diào)用,用接口隱示的聲明,用類(lèi)顯示的實(shí)現(xiàn)調(diào)用,對(duì)于訪問(wèn)SQLServer數(shù)據(jù)庫(kù)具體的代碼是:
圖2 ISqlUserDAL dal=new Demo.DAL.SqlUserDAL();
如果需要訪問(wèn)Access庫(kù),稍加改動(dòng)就變成訪問(wèn)Access庫(kù),具體代碼是:
ISqlUserDAL dal=new Demo.AccessDAL.AccessUserDAL();
第二階段:首先給學(xué)生提出問(wèn)題:接口就可以實(shí)現(xiàn)訪問(wèn)不同的數(shù)據(jù)庫(kù)我們?yōu)槭裁床捎霉S模式呢?原因有兩個(gè):第一是客戶(hù)提出新需求,自己不改變?cè)创a就更換為其他數(shù)據(jù)庫(kù);第二是從開(kāi)發(fā)公司考慮,為了適應(yīng)不同的數(shù)據(jù)庫(kù),每次需要修改BLL層源代碼,再編譯程序,發(fā)布程序比較麻煩。那么具體實(shí)現(xiàn)步驟是創(chuàng)建新的工廠項(xiàng)目類(lèi),添加類(lèi)SFactory,然后在類(lèi)中實(shí)現(xiàn)返回實(shí)現(xiàn)產(chǎn)品接口的方法,具體代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Demo.SFactory
{
public class Factory
{
static string strDBType=
System.Configuration.ConfigurationManager.AppSettings["DBType"].ToString();
public static Demo.DAL.IUserDALCreatUserInfo()
{switch(strDBType)
{ case"sqlServer":
return new Demo.DAL.UserDAL();
break;
case "Access":
return new Demo.AccessDAL.UserAccessDAL();
break;
default:
return null;
}
}
}
}
通過(guò)Web.Config讀取配置數(shù)據(jù),針對(duì)不同數(shù)據(jù)庫(kù),返回不同實(shí)現(xiàn)接口的對(duì)象,最后修改BLL層的調(diào)用方式為簡(jiǎn)單工廠調(diào)用,用接口隱示聲明,但是實(shí)現(xiàn)通過(guò)工廠創(chuàng)建,代碼如下:
privatestatic IUserInfodb=SFactory.CreateDalUserInfoInstance();
配置文件App.Config代碼如下:
="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:Three-FrameDemoUIDemoUIinDebugAccessDb.mdb"/> 這樣我們就可以通過(guò)修改配置文件實(shí)現(xiàn)不同數(shù)據(jù)庫(kù)的訪問(wèn),實(shí)現(xiàn)了簡(jiǎn)單工廠的設(shè)計(jì)模式。 第三階段:講解抽象工廠的實(shí)現(xiàn),有了簡(jiǎn)單工廠,為什么還要使用抽象工廠呢,原因是一個(gè)大的軟件項(xiàng)目中包括很多的模塊,不同的模塊就要?jiǎng)?chuàng)建不同的接口,那么如何返回很多實(shí)現(xiàn)接口的對(duì)象呢,在簡(jiǎn)單工廠模式中只能編寫(xiě)多塊相似的代碼,通過(guò)判斷數(shù)據(jù)庫(kù)的類(lèi)型返回具體的對(duì)象,這樣就造成大量的代碼冗余。這里采用優(yōu)化的方法,即抽象公共的部分,通過(guò)抽象類(lèi)調(diào)用具體的實(shí)現(xiàn)類(lèi),可以產(chǎn)生一批有關(guān)聯(lián)的產(chǎn)品,例如通過(guò)配置文件讀取是Access數(shù)據(jù)庫(kù)類(lèi)型,那么得到是Access的工廠,工廠里的產(chǎn)品都是通過(guò)訪問(wèn)Access數(shù)據(jù)庫(kù)數(shù)據(jù)產(chǎn)生的產(chǎn)品??梢哉f(shuō)對(duì)于簡(jiǎn)單工廠模式一次只能創(chuàng)建一個(gè)對(duì)象,而對(duì)于抽象工廠模式實(shí)現(xiàn)一次創(chuàng)建一系列相互依賴(lài)對(duì)象的需求。 具體的演示實(shí)現(xiàn)步驟是首先通過(guò)修改前面的編寫(xiě)的簡(jiǎn)單工廠SFactory類(lèi)為抽象工廠類(lèi),添加相應(yīng)的抽象方法,通過(guò)讀取對(duì)應(yīng)的配置文件,返回實(shí)現(xiàn)抽象類(lèi)的工廠;然后創(chuàng)建一個(gè)具體工廠類(lèi)SQLFactory繼承這個(gè)抽象工廠類(lèi),重寫(xiě)抽象方法,只返回具體SQLServer庫(kù)的實(shí)現(xiàn);最后創(chuàng)建新的Access具體工廠類(lèi),添加類(lèi)AccessFactory,讓它也繼承抽象工廠類(lèi),重寫(xiě)抽象方法。另外,不要忘記修改BLL層的調(diào)用方式為抽象工廠調(diào)用,具體的代碼是先得到一個(gè)工廠,然后再得到相應(yīng)產(chǎn)品。具體的代碼是: private static AbsDALFactory factory=AbsDALFactory.Choose-Factory(); private static IUserInfo db=factory.CreateDalUserInfoInstance(); 這樣我們就將數(shù)據(jù)訪問(wèn)層的內(nèi)容進(jìn)行了細(xì)化,首先引入接口,再使用簡(jiǎn)單工廠,然后引入抽象工廠模式,通過(guò)演示讓學(xué)員明白為什么要使用簡(jiǎn)單工廠和抽象工廠以及如何使用它。具體思路見(jiàn)圖3。 圖3 使用簡(jiǎn)單工廠和抽象工廠的具體思路 這里演示完成后,如果學(xué)生還無(wú)法透徹地理解抽象工廠模式,下面共享一個(gè)生活案例給大家,通過(guò)案例剖析抽象工廠的實(shí)現(xiàn)方式: 圖4 抽象工廠 客戶(hù)是什么?這里我們說(shuō)的客戶(hù)是指調(diào)用者,具體而言如網(wǎng)站的美工設(shè)計(jì)人員。那么地圖是什么呢?指配置文件,快餐點(diǎn)比喻我們的抽象工廠,漢堡和雞腿比喻抽象產(chǎn)品,客戶(hù)即調(diào)用者只知道這些,具體的哪個(gè)快餐店,如何制作什么漢堡,客戶(hù)并不關(guān)心,只要能到最方便的快餐店吃到漢堡,填飽肚子即可。具體的工廠是肯德基和麥當(dāng)勞,具體產(chǎn)品是KFC的漢堡、KFC雞腿,他們這一組是相關(guān)的,另外一組是McDonald漢堡、McDonald雞腿,他們兩個(gè)是相關(guān)的,是可以左手拿著McDonald漢堡,右手拿著Mc-Donald雞腿狼吞虎咽的;我們把相關(guān)的產(chǎn)品,稱(chēng)為一系列的產(chǎn)品,你還想吃薯?xiàng)l,稍微擴(kuò)展一下,加一個(gè)薯?xiàng)l的產(chǎn)品,包括抽象薯?xiàng)l和具體的薯?xiàng)l。如下圖所示:藍(lán)色框圖中的肯德基的漢堡、雞腿和薯?xiàng)l是相關(guān)的,一系列的,由此可以看出抽象工廠設(shè)計(jì)模式給客戶(hù)提供的不再是單一的產(chǎn)品,而是提供一批系列的產(chǎn)品。 圖5 抽象工廠二 通過(guò)層層深入的代碼演示,再結(jié)合生活案例來(lái)理解抽象工廠,希望大家能夠掌握簡(jiǎn)單三層到抽象工廠的講解技巧,在實(shí)際的授課中深入淺出、步步為營(yíng)熟練地進(jìn)行代碼演示,讓學(xué)員徹底理解并會(huì)使用抽象工廠設(shè)計(jì)模式。 Explains the Abstract Factory Pattern from the Shallow to the Deep Using the Case Teaching Method Xu Hong The article mainly elaborated the abstract factory pattern,through carries on the explanation using the case teaching method,will let the student understand and use the abstract plant design pattern thoroughly. abstract factory pattern;case teaching method;explanation G712 A 1000-8136(2010)32-0107-033 總結(jié)