C#23種設(shè)計(jì)模式 第4章 工廠方法(Factory Method)_第1頁(yè)
C#23種設(shè)計(jì)模式 第4章 工廠方法(Factory Method)_第2頁(yè)
C#23種設(shè)計(jì)模式 第4章 工廠方法(Factory Method)_第3頁(yè)
C#23種設(shè)計(jì)模式 第4章 工廠方法(Factory Method)_第4頁(yè)
C#23種設(shè)計(jì)模式 第4章 工廠方法(Factory Method)_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

工廠方法模式(FactoryMethod)——.NETTerrylee,20041工廠方法模式(FactoryMethod)——.NETTerrylee,200412概述在軟件系統(tǒng)中,經(jīng)常面臨著“某個(gè)對(duì)象”的創(chuàng)建工作,由于需求的變化,這個(gè)對(duì)象的具體實(shí)現(xiàn)經(jīng)常面臨著劇烈的變化,但是它卻擁有比較穩(wěn)定的接口。如何應(yīng)對(duì)這種變化?提供一種封裝機(jī)制來(lái)隔離出“這個(gè)易變對(duì)象”的變化,從而保持系統(tǒng)中“其它依賴(lài)該對(duì)象的對(duì)象”不隨著需求的改變FactoryMethod意圖定義一個(gè)用戶(hù)創(chuàng)建對(duì)象的接口,讓子類(lèi)決定實(shí)例化哪一個(gè)類(lèi)。FactoryMethod化延遲到其子類(lèi)。結(jié)構(gòu)圖生活中的例子工廠方法定義一個(gè)用于創(chuàng)建對(duì)象的接口,但是讓子類(lèi)決定實(shí)例化哪個(gè)類(lèi)。壓注成型演示了這種模式。塑料玩具制造商加工塑料粉,將塑料注入到希望形狀的模具中。玩具的類(lèi)別(車(chē),人物等等)是由模具決定的。工廠方法解說(shuō)這個(gè)核心類(lèi)僅僅負(fù)責(zé)給出具體工廠必須實(shí)現(xiàn)的接口,而不接觸哪一個(gè)產(chǎn)品類(lèi)被實(shí)例化這種細(xì)節(jié)。FactoryMethod模式中,工廠類(lèi)與產(chǎn)品類(lèi)往往具有平行的等級(jí)結(jié)構(gòu),它們之間一一對(duì)應(yīng)?,F(xiàn)在我們考慮一個(gè)日志記錄的例子(FactoryMethod模式,實(shí)際項(xiàng)目中的日志記錄不會(huì)這么去做,也要比這復(fù)雜一些FileLogEventLog兩種方式。在這里我們先不談設(shè)計(jì)模式,那么這個(gè)日志記錄的類(lèi)就很好實(shí)現(xiàn)了:///<summary>///日志記錄類(lèi)///</summary>publicclassLog5 {67 publicvoidWriteEvent()8 {9 Console.WriteLine("EventLogSuccess!");10 }1112 publicvoidWriteFile()13 {14 Console.WriteLine("FileLogSuccess!");15 }1617 publicvoidWrite(stringLogType)18 {19 switch(LogType.ToLower())20 {case"event":WriteEvent();break;24case"file":WriteFile();break;28default:break;31 }32 }33 }34DatabaseLog,那就要修改Log語(yǔ)句在不斷的變化,這樣就引起了整個(gè)EventLogFileLog是兩種完全不同的記錄方式,它們之間不應(yīng)該存在必然的聯(lián)系,而應(yīng)該把它們分別作為單獨(dú)的對(duì)象來(lái)對(duì)待。///<summary>///EventLog類(lèi)///</summary>publicclassEventLog5 {6 publicvoidWrite()7 {8 Console.WriteLine("EventLogWriteSuccess!");9 }10}11///<summary>///FileLog類(lèi)///</summary>publicclassFileLog16 {17 publicvoidWrite()18 {19 Console.WriteLine("FileLogWriteSuccess!");20 }21}22進(jìn)一步抽象,為它們抽象出一個(gè)共同的父類(lèi),結(jié)構(gòu)圖如下:實(shí)現(xiàn)代碼:///<summary>///Log///</summary>publicabstractclass5 {6 publicabstractvoidWrite();7}8此時(shí)EventLog和FileLog類(lèi)的代碼應(yīng)該如下:///<summary>///EventLog類(lèi)///</summary>publicclassEventLog:Log5 {6 publicoverridevoidWrite()7 {8 Console.WriteLine("EventLogWriteSuccess!");9 }10}///<summary>///FileLog類(lèi)///</summary>publicclassFileLog:Log15 {16 publicoverridevoidWrite()17 {18 Console.WriteLine("FileLogWriteSuccess!");19 }20}21DatabaseLogLogEventLogFileLog類(lèi),這樣的設(shè)計(jì)滿(mǎn)足了類(lèi)程序中,我們要使用某一種日志記錄方式,也許會(huì)用到如下這樣的語(yǔ)句:EventLogeventlog=newEventLog();eventlog.Write();EventLogFactoryMethod模式了,每一個(gè)日志記錄的對(duì)象就是工廠所生成的產(chǎn)品,既然有兩種記錄方式,那就需要兩個(gè)不同的工廠去生產(chǎn)了,代碼如下:///<summary>///EventFactory類(lèi)///</summary>publicclassEventFactory5 {6 publicEventLogCreate()7 {8 returnnewEventLog();9 }10}///<summary>///FileFactory類(lèi)///</summary>publicclassFileFactory15 {16 publicFileLogCreate()17 {18 returnnewFileLog();19 }20}21接口,結(jié)構(gòu)圖如下:實(shí)現(xiàn)代碼如下:///<summary>///LogFactory類(lèi)///</summary>publicabstractclassLogFactory5 {6 publicabstractLogCreate();7}8此時(shí)兩個(gè)具體工廠的代碼應(yīng)該如下:///<summary>///EventFactory類(lèi)///</summary>publicclassEventFactory:LogFactory5 {6 publicoverrideEventLogCreate()7 {8 returnnewEventLog();9 }10}///<summary>///FileFactory類(lèi)///</summary>publicclassFileFactory:LogFactory15 {16 publicoverrideFileLogCreate()17 {18 returnnewFileLog();19 }20}21actoryMethod的過(guò)程。這樣達(dá)到了我們應(yīng)用程序和具體日志記錄對(duì)象之間解耦的目的了嗎?看一下此時(shí)客戶(hù)端程序代碼:///<summary>///App類(lèi)///</summary>publicclassApp5 {6 publicstaticvoidMain(string[]args)7 {8 LogFactoryfactory=newEventFactory();910 Loglog=factory.Create();1112 13 }14}15Log對(duì)象的創(chuàng)建是頻繁的,在這里我們可以把LogFactoryfactory=newEventFactory();Log只要修改一處為:LogFactoryfactory=newFileFactory();改,但是我們可以盡量做到只修改一處。其實(shí)利用.NET的特性,我們可以避免這種不必要的修改。下面我們利用.NET中的反射機(jī)制來(lái)相應(yīng)的配置文件中設(shè)置如下:<appSettings><addkey="factoryName"value="EventFactory"></add></appSettings>4此時(shí)客戶(hù)端代碼如下:///<summary>///App類(lèi)///</summary>publicclassApp5 {6 publicstaticvoidMain(string[]args)7 {8 stringstrfactoryName=ConfigurationSettings.AppSettings["factoryName"];9LogFactoryfactory;factory=(LogFactory)Assembly.Load("FactoryMethod").CreateInstance("FactoryMethod."+strfactoryName);12Loglog=factory.Create();15 }16}17現(xiàn)在我們看到,在引進(jìn)新產(chǎn)品(日志記錄方式)增加新的產(chǎn)品類(lèi)和新的工廠類(lèi)(ASP.NETHTTP通道中的應(yīng)用FactoryMethodASP.NETHTTPASP.NETHTTPystem.Web命名空間下的一個(gè)類(lèi),WEBServerHTTPSessionSystem.Web.HttpApplicationFactoryHttpRuntimeHTTPHttpContext實(shí)例,HttpRuntimeHttpApplicationHttpApplicationFactory.GetApplicationInstanceHttpContextGetApplicationInstanceHttpContext實(shí)例來(lái)確定針對(duì)這個(gè)請(qǐng)或者一個(gè)繼承于ASP.Global_asax的類(lèi)的實(shí)例)將直接從應(yīng)用程序池中返回,否則針對(duì)該虛擬路徑將創(chuàng)建一HttpApplication對(duì)象并返回。如下圖所示:HttpApplicationFactory.GetApplicationInstanceHttpContext的參數(shù),創(chuàng)建的所有對(duì)象(產(chǎn)品)HttpApplicationGetApplicationInstance的實(shí)現(xiàn):1internalstaticIHttpHandlerGetApplicationInstance(HttpContextcontext)2 {3 if(HttpApplicationFactory._customApplication!=null)4 {5 returnHttpApplicationFactory._customApplication;6 }7 if(HttpDebugHandler.IsDebuggingRequest(context))8 {9 returnnewHttpDebugHandler();10 }11 if(!HttpApplicationFactory._theApplicationFactory._inited)12 {13 lock(HttpApplicationFactory._theApplicationFactory)14 {15 if(!HttpApplicationFactory._theApplicationFactory._inited)16 {tory.Init(context);tory._inited=true;19 }20 }21 }22 returnHttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context);23}24System.Web.IHttpHandlerFactory我們來(lái)做進(jìn)一步的探索,HttpApplicationHandler對(duì)象來(lái)處理資源請(qǐng)求,HttpApplication的主要任務(wù)就是找到真正處理請(qǐng)求的類(lèi)。HttpApplication首先確定了HandlerMachine.config文件中的配置區(qū)<httphandlers>Machine.config中對(duì)*.aspx的System.Web.UI.PageHandlerFactory*.ashxSystem.Web.UI.SimpleHandlerFactoryIhttpHandlerFactory接口的具體類(lèi):<httpHandlers><addverb="*"path="*.aspx"type="System.Web.UI.PageHandlerFactory"/><addverb="*"path="*.ashx"type="System.Web.UI.SimpleHandlerFactory"/></httpHandlers>這個(gè)配置區(qū)建立了資源請(qǐng)求的類(lèi)型和處理請(qǐng)求的類(lèi)之間的一個(gè)映射集。如果一個(gè).aspx頁(yè)面發(fā)System.Web.UI.PageHandlerFactory調(diào)用IHttpHandlerFactoryGetHandlerHandler對(duì)象。當(dāng)一sample.aspxPageHandlerFactoryASP.SamplePage_aspx對(duì)象(具體產(chǎn)品),如下圖:IHttpHandlerFactory工廠:1publicinterfaceIHttpHandlerFactory2 {//MethodsIHttpHandlerGetHandler(HttpContextcontext,stringrequestType,stringurl,stringpathTranslated);voidReleaseHandler(IHttpHandlerhandler);6}7抽象工廠角色:IHttpHandlerFactory具體工廠角色:PageHandlerFactory抽象工廠角色:IHttpHandlerFactory具體工廠角色:PageHandlerFactory抽象產(chǎn)品角色:IHttpHandler具體產(chǎn)品角色:具體產(chǎn)品角色:ASP.SamplePage_aspx進(jìn)一步去理解IHttpHandlerFactoryIHttpHandler這兩個(gè)接口。1 publicclassHttpHandlerFactoryImpl:IHttpHandlerFactory{2IHttpHandlerIHttpHandlerFactory.GetHandler(HttpContextcontext,StringrequestType,Stringurl,StringpathTranslated){67 returnnewHttpHandlerImpl();89 10voidIHttpHandlerFactory.ReleaseHandler(IHttpHandlerhandler){/*no-op*/}1314}//HttpHandlerFactoryImpl1516 publicclassHttpHandlerImpl:IHttpHandler{1718 voidIHttpHandler.ProcessRequest(HttpContextcontext){1920 context.Response.Write("samplehandlerinvoked2122 }//ProcessRequest23

");24 boolIHttpHandler.IsReusable{get{returnfalse;}}2526}//HttpHandlerImpl27第二步需要在配置文件中建立資源請(qǐng)求類(lèi)型和處理程序之間的映射。我們希望當(dāng)請(qǐng)求的類(lèi)型為sample時(shí)進(jìn)入我們自定義的處理程序,如下:<httpHandlers><addverb="*"path="*.sample"type="HttpHandlerFactoryImpl,SampleHandler"/></httpHandlers>最后一步我們需要把文件擴(kuò)展e映射到TI擴(kuò)展(dll)IISASP.NET*.sample將簡(jiǎn)ASP.NETHTTP處理程序不會(huì)被調(diào)用。InternetWeb站點(diǎn),選擇屬性,移動(dòng)到主目錄選項(xiàng)頁(yè),并點(diǎn)aspnet_isapi.dll文件路徑,在擴(kuò)展字段輸入.sample。其它字段不用處理;該對(duì)話(huà)框如下所示:在.NETFrame

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論