0抽象工廠模式詳解(abstract-factory)_第1頁
0抽象工廠模式詳解(abstract-factory)_第2頁
0抽象工廠模式詳解(abstract-factory)_第3頁
0抽象工廠模式詳解(abstract-factory)_第4頁
0抽象工廠模式詳解(abstract-factory)_第5頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

抽象工廠模式概述在軟件系統(tǒng)中,經(jīng)常面臨著“一系列相互依賴的對象〞的創(chuàng)立工作;同時由于需求的變化,往往存在著更多系列對象的創(chuàng)立工作。如何應(yīng)對這種變化?如何繞過常規(guī)的對象的創(chuàng)立方法〔new〕,提供一種“封裝機(jī)制〞來防止客戶程序和這種“多系列具體對象創(chuàng)立工作〞的緊耦合?這就是我們要說的抽象工廠模式。意圖提供一個創(chuàng)立一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類模型圖邏輯模型:物理模型:生活中的例子抽象工廠的目的是要提供一個創(chuàng)立一系列相關(guān)或相互依賴對象的接口,而不需要指定它們具體的類。這種模式可以汽車制造廠所使用的金屬沖壓設(shè)備中找到。這種沖壓設(shè)備可以制造汽車車身部件。同樣的機(jī)械用于沖壓不同的車型的右邊車門、左邊車門、右前擋泥板、左前擋泥板和引擎罩等等。通過使用轉(zhuǎn)輪來改變沖壓盤,這個機(jī)械產(chǎn)生的具體類可以在三分鐘內(nèi)改變。抽象工廠之新解虛擬案例中國企業(yè)需要一項簡單的財務(wù)計算:每月月底,財務(wù)人員要計算員工的工資。員工的工資=(根本工資+獎金-個人所得稅)。這是一個放之四海皆準(zhǔn)的運(yùn)算法那么。為了簡化系統(tǒng),我們假設(shè)員工根本工資總是4000美金。中國企業(yè)獎金和個人所得稅的計算規(guī)那么是: 獎金=根本工資(4000)*10% 個人所得稅=(根本工資+獎金)*40%我們現(xiàn)在要為此構(gòu)建一個軟件系統(tǒng)〔代號叫Softo〕,滿足中國企業(yè)的需求。案例分析獎金(Bonus)、個人所得稅(Tax)的計算是Softo系統(tǒng)的業(yè)務(wù)規(guī)那么(Service)。工資的計算(Calculator)那么調(diào)用業(yè)務(wù)規(guī)那么(Service)來計算員工的實(shí)際工資。工資的計算作為業(yè)務(wù)規(guī)那么的前端(或者客戶端Client)將提供給最終使用該系統(tǒng)的用戶(財務(wù)人員)使用。針對中國企業(yè)為系統(tǒng)建模根據(jù)上面的分析,為Softo系統(tǒng)建模如下:代碼:org.cedar.chinese針對美國企業(yè)為系統(tǒng)建模為了拓展國際市場,我們要把該系統(tǒng)移植給美國公司使用。美國企業(yè)的工資計算同樣是:員工的工資=根本工資+獎金-個人所得稅。但是他們的獎金和個人所得稅的計算規(guī)那么不同于中國企業(yè):美國企業(yè)獎金和個人所得稅的計算規(guī)那么是:獎金=根本工資*15%個人所得稅=(根本工資*5%+獎金*25%)根據(jù)前面為中國企業(yè)建模經(jīng)驗(yàn),我們僅僅將ChineseTax、ChineseBonus修改為AmericanTax、AmericanBonus。修改后的模型如下:代碼:.american

整合成通用系統(tǒng)讓我們回憶一下該系統(tǒng)的開展歷程:最初,我們只考慮將Softo系統(tǒng)運(yùn)行于中國企業(yè)。但隨著MaxDO公司業(yè)務(wù)向海外拓展,MaxDO需要將該系統(tǒng)移植給美國使用。移植時,MaxDO不得不拋棄中國企業(yè)的業(yè)務(wù)規(guī)那么類ChineseTax和ChineseBonus,然后為美國企業(yè)新建兩個業(yè)務(wù)規(guī)那么類:AmericanTax,AmericanBonus。最后修改了業(yè)務(wù)規(guī)那么調(diào)用Calculator類。結(jié)果我們發(fā)現(xiàn):每當(dāng)Softo系統(tǒng)移植的時候,就拋棄原來的類?,F(xiàn)在,如果中國聯(lián)想集團(tuán)要購置該系統(tǒng),我們不得不再次拋棄AmericanTax,AmericanBonus,修改回原來的業(yè)務(wù)規(guī)那么。一個可以立即想到的做法就是在系統(tǒng)中保存所有業(yè)務(wù)規(guī)那么模型,即保存中國和美國企業(yè)工資運(yùn)算規(guī)那么。

通過保存中國企業(yè)和美國企業(yè)的業(yè)務(wù)規(guī)那么模型,如果該系統(tǒng)在美國企業(yè)和中國企業(yè)之間切換時,我們僅僅需要修改Caculator類即可。讓移植工作更簡單前面系統(tǒng)的整合問題在于:當(dāng)系統(tǒng)在客戶在美國和中國企業(yè)間切換時仍然需要修改Caculator代碼。一個維護(hù)性良好的系統(tǒng)應(yīng)該遵循“開閉原那么〞。即:封閉對原來代碼的修改,開放對原來代碼的擴(kuò)展〔如類的繼承,接口的實(shí)現(xiàn)〕我們發(fā)現(xiàn)不管是中國企業(yè)還是美國企業(yè),他們的業(yè)務(wù)運(yùn)規(guī)那么都采用同樣的計算接口。于是很自然地想到建立兩個業(yè)務(wù)接口類Tax,Bonus,然后讓AmericanTax、AmericanBonus和ChineseTax、ChineseBonus分別實(shí)現(xiàn)這兩個接口,據(jù)此修正后的模型如下:代碼:er為業(yè)務(wù)規(guī)那么增加工廠方法然而,上面增加的接口幾乎沒有解決任何問題,因?yàn)楫?dāng)系統(tǒng)的客戶在美國和中國企業(yè)間切換時Caculator代碼仍然需要修改。只不過修改少了兩處,但是仍然需要修改ChineseBonus,ChineseTax局部。致命的問題是:我們需要將這個移植工作轉(zhuǎn)包給一個叫Hippo的軟件公司。由于版權(quán)問題,我們并未提供Softo系統(tǒng)的源碼給Hippo公司,因此Hippo公司根本無法修改Calculator,導(dǎo)致實(shí)際上移植工作無法進(jìn)行。為此,我們考慮增加一個工具類(命名為Factory),代碼如下:org.cedar.factory不錯,我們解決了一個大問題,設(shè)想一下:當(dāng)該系統(tǒng)從中國企業(yè)移植到美國企業(yè)時,我們現(xiàn)在需要做什么?答案是:對于Caculator類我們什么也不用做。我們需要做的是修改Factory類,修改結(jié)果如下:org.cedar.factory為系統(tǒng)增加抽象工廠方法很顯然,前面的解決方案帶來了一個副作用:就是系統(tǒng)不但增加了新的類Factory,而且當(dāng)系統(tǒng)移植時,移植工作僅僅是轉(zhuǎn)移到Factory類上,工作量并沒有任何縮減,而且還是要修改系統(tǒng)的源碼。從Factory類在系統(tǒng)移植時修改的內(nèi)容我們可以看出:實(shí)際上它是專屬于美國企業(yè)或者中國企業(yè)的。名稱上應(yīng)該叫AmericanFactory,ChineseFactory更適宜.解決方案是增加一個抽象工廠類AbstractFactory,增加一個靜態(tài)方法,該方法根據(jù)一個配置文件(App.config或者Web.config)一個項(比方factoryName)動態(tài)地判斷應(yīng)該實(shí)例化哪個工廠類,這樣,我們就把移植工作轉(zhuǎn)移到了對配置文件的修改。修改后的模型和代碼:

代碼:org.cedar.abstractfactory采用上面的解決方案,當(dāng)系統(tǒng)在美國企業(yè)和中國企業(yè)之間切換時,我們需要做什么移植工作?答案是:我們僅僅需要修改配置文件,將factoryName的值改為American。修改配置文件的工作很簡單,只要寫一篇幅配置文檔說明書提供給移植該系統(tǒng)的團(tuán)隊(比方Hippo公司)就可以方便地切換使該系統(tǒng)運(yùn)行在美國或中國企業(yè)。最后的修正〔不是最終方案〕前面的解決方案幾乎很完美,但是還有一點(diǎn)瑕疵,瑕疵雖小,但可能是致命的??紤]一下,現(xiàn)在日本NEC公司決定購置該系統(tǒng),NEC公司的工資的運(yùn)算規(guī)那么遵守的是日本的法律。如果采用上面的系統(tǒng)構(gòu)架,這個移植我們要做哪些工作呢?1. 增加新的業(yè)務(wù)規(guī)那么類JapaneseTax,JapaneseBonus分別實(shí)現(xiàn)Tax和Bonus接口。2. 修改AbstractFactory的getInstance方法,增加elseif(factoryName.equals("Japanese")){....注意:系統(tǒng)中增加業(yè)務(wù)規(guī)那么類不是模式所能解決的,無論采用什么設(shè)計模式,JapaneseTax,JapaneseBonus總是少不了的。〔即增加了新系列產(chǎn)品〕我們真正不能接受的是:我們?nèi)匀恍抟薷南到y(tǒng)中原來的類(AbstractFactory)。前面提到過該系統(tǒng)的移植工作,我們可能轉(zhuǎn)包給一個叫Hippo的軟件公司。為了維護(hù)版權(quán),未將該系統(tǒng)的源碼提供給Hippo公司,那么Hippo公司根本無法修改AbstractFactory,所以系統(tǒng)移植其實(shí)無從談起,或者說系統(tǒng)移植總要開發(fā)人員親自參與。代碼:org.cedar.abstractfactory這樣,在我們編寫的代碼中就不會出現(xiàn)Chinese,American,Japanese等這樣的字眼了。小結(jié)最后那幅圖是最終版的系統(tǒng)模型圖。我們發(fā)現(xiàn)作為客戶端角色的Calculator僅僅依賴抽象類,它不必去理解中國和美國企業(yè)具體的業(yè)務(wù)規(guī)那么如何實(shí)現(xiàn),Calculator面對的僅僅是業(yè)務(wù)規(guī)那么接口Tax和Bonus。Softo系統(tǒng)的實(shí)際開發(fā)的分工可能是一個團(tuán)隊專門做業(yè)務(wù)規(guī)那么,另一個團(tuán)隊專門做前端的業(yè)務(wù)規(guī)那么組裝。抽象工廠模式有助于這樣的團(tuán)隊的分工:兩個團(tuán)隊通訊的約定是業(yè)務(wù)接口,由抽象工廠作為紐帶粘合業(yè)務(wù)規(guī)那么和前段調(diào)用,大大降低了模塊間的耦合性,提高了團(tuán)隊開發(fā)效率。完完全全地理解抽象工廠模式的意義非常重大,完完全全地理解抽象工廠模式的意義非常重大,可以說對它的理解是你對OOP理解上升到一個新的里程碑的重要標(biāo)志。學(xué)會了用抽象工廠模式編寫框架類,你將理解OOP的精華:面向接口編程.。應(yīng)對“新對象〞抽象工廠模式主要在于應(yīng)對“新系列〞的需求變化。其缺點(diǎn)在于難于應(yīng)付“新對象〞的需求變動。如果在開發(fā)中出現(xiàn)了新對象,該如何去解決呢?這個問題并沒有一個好的答案,下面我們看一下李建忠老師的答復(fù):“GOF?設(shè)計模式?中提出過一種解決方法,即給創(chuàng)立對象的操作增加參數(shù),但這種做法并不能令人滿意。事實(shí)上,對于新系列加新對象,就我所知,目前還沒有完美的做法,只有一些演化的思路,這種變化實(shí)在是太劇烈了,因?yàn)橄到y(tǒng)對于新的對象是完全陌生的。〞實(shí)現(xiàn)要點(diǎn)

抽象工廠將產(chǎn)品對象的創(chuàng)立延遲到它的具體工廠的子類。

如果沒有應(yīng)對“多系列對象創(chuàng)立〞的需求變化,那么沒有必要使用抽象工廠模式,這時候使用簡單的靜態(tài)工廠完全可以。

系列對象指的是這些對象之間有相互依賴、或作用的關(guān)系,例如游戲開發(fā)場景中的“道路〞與“房屋〞的依賴,“道路〞與“地道〞的依賴。

抽象工廠模式經(jīng)常和工廠方法模式共同組合來應(yīng)對“對象創(chuàng)立〞的需求變化。

通常在運(yùn)行時刻創(chuàng)立一個具體工廠類的實(shí)例,這一具體工廠的創(chuàng)立具有特定實(shí)現(xiàn)的產(chǎn)品對象,為創(chuàng)立不同的產(chǎn)品對象,客戶應(yīng)使用不同的具體工廠。

把工廠作為單件,一個應(yīng)用中一般每個產(chǎn)品系列只需一個具體工廠的實(shí)例,因此,工廠通常最好實(shí)現(xiàn)為一個單件模式。

創(chuàng)立產(chǎn)品,抽象工廠僅聲明一個創(chuàng)立產(chǎn)品的接口,真正創(chuàng)立產(chǎn)品是由具體產(chǎn)品類創(chuàng)立的,最通常的一個方法是為每一個產(chǎn)品定義一個工廠方法,一個具體的工廠將為每個產(chǎn)品重定義該工廠方法以指定產(chǎn)品,雖然這樣的實(shí)現(xiàn)很簡單,但它確要求每個產(chǎn)品系列都要有一個新的具體工廠子類,即使這些產(chǎn)品系列的差異很小。優(yōu)點(diǎn)

別離了具體的類。抽象工廠模式幫助你控制一個應(yīng)用創(chuàng)立的對象的類,因?yàn)橐粋€工廠封裝創(chuàng)立產(chǎn)品對象的責(zé)任和過程。它將客戶和類的實(shí)現(xiàn)別離,客戶通過他們的抽象接口操縱實(shí)例,產(chǎn)品的類名也在具體工廠的實(shí)現(xiàn)中被別離,它們不出現(xiàn)在客戶代碼中。

它使得易于交換產(chǎn)品系列。一個具體工廠類在一個應(yīng)用中僅出現(xiàn)一次——即在它初始化的時候。這使得改變一個應(yīng)用的具體工廠變得很容易。它只需改變具體的工廠即可使用不同的產(chǎn)品配置,這是因?yàn)橐粋€抽象工廠創(chuàng)立了一個完整的產(chǎn)品系列,所以整個產(chǎn)品系列會立刻改變。

它有利于產(chǎn)品的一致性。當(dāng)一個系列的產(chǎn)品對象被設(shè)計成一起工作時,一個應(yīng)用一次只能使用同一個系列中的對象,這一點(diǎn)很重要,而抽象工廠很容易實(shí)現(xiàn)這一點(diǎn)。缺點(diǎn)

難以支持新種類的產(chǎn)品。難以擴(kuò)展抽象工廠以生產(chǎn)新種類的產(chǎn)品。這是因?yàn)槌橄蠊S幾口確定了可以被創(chuàng)立的產(chǎn)品集合,支持新種類的產(chǎn)品就需要擴(kuò)展該工廠接口,這將涉及抽象工廠類及其所有子類的改變。適用性在以下情況下應(yīng)當(dāng)考慮使用抽象工廠模式:

一個系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實(shí)例如何被創(chuàng)立、組合和表達(dá)的細(xì)節(jié),這對于所有形態(tài)的工廠模式都是重要的。

這個系統(tǒng)有多于一個的產(chǎn)品族,而系統(tǒng)只消費(fèi)其中某一產(chǎn)品族。

同屬于同一個產(chǎn)品

溫馨提示

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

評論

0/150

提交評論