相關閱讀 |
>>> 技術話題—商業文明的嶄新時代 >>> | 簡體 傳統 |
2005.11.15 李建忠
new的問題
常規的對象創建方法:
new的問題:
-實現依賴,不能應對“具體實例化類型”的變化
解決思路:
-封裝變化點——哪里變化,封裝哪里
-潛臺詞:如果沒有變化,當然不需要額外的封裝!
工廠模式的緣起
變化點在“對象創建”,因此就封裝“對象創建”
面向接口編程——依賴接口,而非依賴實現
最簡單的解決方法:
創建一系列相互依賴的對象
假設一個游戲開發場景:
我們需要構造“道路”、“房屋”、“地道”、“叢林”……等等對象
簡單工廠的問題
簡單工廠的問題:
-不能應對“不同系列對象”的變化。比如有不同風格的游戲場景——對應不同風格的道路、房屋、地道……客戶程序相對穩定,但是靜態的簡單工廠卻可能成為變化點。
如何解決:
-使用面向對象的技術來“封裝”變化點
動機(Motivation)
在軟件系統中,經常面臨著“一系列相互依賴的對象”的創建工作;同時,由于需求的變化,往往存在更多系列對象的創建工作。
如何應對這種變化?如何繞過常規的對象創建方法(new),提供一種“封裝機制”來避免客戶程序和這種“多系列具體對象創建工作”的緊耦合?
意圖(Intent)
提供一個接口,讓該接口負責創建一系列“相關或者相互依賴的對象”,無需指定它們具體的類。
——《設計模式》GoF
結構(Structure)
A1和B1是一個系列,A2和B2是另一個系列。ConcreteFactory1是創建系列1的工廠方法,ConcreteFactory2是創建系列2的工廠方法。客戶程序Client只依賴了AbstractFactory和AbstractProductA、AbstractProductB,也就是客戶程序不依賴于具體實現,而是只依賴與抽象類。
如果現在需要創建一個系列3運用到客戶程序,我們只需要再寫一個系列3的工廠,繼承自AbstractFactory,這個工廠提供了2個實現:
CreateProductA();
CreateProductB();
它們分別返回ProductA3(繼承自AbstractProductA)、ProductB3(繼承自AbstractProductB)。
也就是說,如果新增了系列3,Client程序可以完全不用改動,可能只需要該一些配置文件,增加一些新dll就可以應對變化。
游戲框架中的AbstractFactory應用
這個例子里,Road就是AbstractProductA1,Building就是AbstractProductB1,FacilitiesFactory就是AbstractFactory。
客戶程序
可以看出,客戶程序依賴的全部是抽象類,在客戶程序代碼中沒有出現過任何具體的實現類。因為在系列需要變化的時候,是不需要改變抽象類的,只是增加一個抽象類的實現而已,又由于客戶程序只依賴于抽象,所以系列變化的時候客戶程序完全無需變化。
一個現代風格系列的實現
具體現代風格系列工廠實現
應用到具體程序(現代風格)
應用到具體程序(經典風格)
可以看出,風格由Modern改變為Classic的時候,我們封裝好的GameManager客戶程序沒有改變,這就是我們想要的結果。GameManager的邏輯非常復雜,現在它的穩定,能夠大大方便我們的工作。
AbstractFactory模式的幾個要點
1.如果沒有應對“多系列對象創建”的需求變化,則沒有必要使用AbstractFactory模式,這時候使用簡單的靜態工廠完全可以。
2."系列對象"指的是這些對象之間有相互依賴、或作用的關系,例如游戲開發場景中“道路”與“房屋”的依賴,“道路”與“地道”的依賴。
3.AbstractFactory模式主要在于應對“新系列”的需求變動。其缺點在于難以應對“新對象”的需求變動。
4.AbstractFactory模式經常喝FactoryMethod模式共同組合來應對“對象創建”的需求變化。
例如,如果是風格不是經常變化,而是其他內容變化(例如今天要添加道路的類、明天要添加沙漠的類),這樣用這種抽象工廠模式反而會把系統搞的很糟糕,因為抽象工廠類中的子類變化了,所有實現抽象工廠的類都需要去變化,重新實現,重新編譯和部署。
也就是說關鍵要看變化的方向和軸線在哪里。如果變化的軸線在多風格,那抽象工廠模式就很適用;如果變化的軸線在抽象工廠里面的對象,就最好不要使用這種模式。
.NET框架中的AbstractFactory應用
在ASP.Net編譯的時候,首先把aspx頁面文件先編譯成一個類,然后再把CodeBehind又編譯成一個類,CodeBehind的類繼承自Page類,而aspx頁面的類又繼承自CodeBehind類。在aspx頁面中處理的WebControl和HtmlControl實際上用到了AbstractFactory的運用,但是這個運用更多是體現在業務層次。
Builder模式和AbstractFactory模式的區別
Builder模式更強調的是對象部分的構建這樣一個嚴格的過程,它構建的是整個對象的各個部分。它把構建穩定下來之后,各個部分在變化,最后組合成一個整體的對象。
AbstractFactory模式構建的是一組系列交互的對象。
互相依賴、互相交互的對象和一個對象的各個部分是有區別的。
2010.9.22
MSDN 網絡廣播 李建忠 2013-08-22 08:42:15
稱謂:
内容: