鍍金池/ 教程/ Java/ 工廠三兄弟之抽象工廠模式(五)
工廠三兄弟之抽象工廠模式(五)
復雜對象的組裝與創(chuàng)建——建造者模式(一)
工廠三兄弟之工廠方法模式(一)
復雜對象的組裝與創(chuàng)建——建造者模式(二)
確保對象的唯一性——單例模式 (二)
工廠三兄弟之簡單工廠模式(四)
確保對象的唯一性——單例模式 (一)
工廠三兄弟之工廠方法模式(四)
對象的克隆——原型模式(一)
工廠三兄弟之抽象工廠模式(二)
工廠三兄弟之工廠方法模式(三)
工廠三兄弟之抽象工廠模式(一)
工廠三兄弟之抽象工廠模式(四)
確保對象的唯一性——單例模式 (三)
工廠三兄弟之簡單工廠模式(三)
對象的克隆——原型模式(二)
復雜對象的組裝與創(chuàng)建——建造者模式(三)
對象的克隆——原型模式(四)
確保對象的唯一性——單例模式(四)
工廠三兄弟之簡單工廠模式(一)
工廠三兄弟之簡單工廠模式(二)
對象的克隆——原型模式(三)
工廠三兄弟之抽象工廠模式(三)
確保對象的唯一性——單例模式(五)
工廠三兄弟之工廠方法模式(二)

工廠三兄弟之抽象工廠模式(五)

“開閉原則”的傾斜性

Sunny 公司使用抽象工廠模式設計了界面皮膚庫,該皮膚庫可以較為方便地增加新的皮膚,但是現(xiàn)在遇到一個非常嚴重的問題:由于設計時考慮不全面,忘記為單選按鈕(RadioButton)提供不同皮膚的風格化顯示,導致無論選擇哪種皮膚,單選按鈕都顯得那么“格格不入”。Sunny 公司的設計人員決定向系統(tǒng)中增加單選按鈕,但是發(fā)現(xiàn)原有系統(tǒng)居然不能夠在符合“開閉原則”的前提下增加新的組件,原因是抽象工廠 SkinFactory 中根本沒有提供創(chuàng)建單選按鈕的方法,如果需要增加單選按鈕,首先需要修改抽象工廠接口 SkinFactory,在其中新增聲明創(chuàng)建單選按鈕的方法,然后逐個修改具體工廠類,增加相應方法以實現(xiàn)在不同的皮膚中創(chuàng)建單選按鈕,此外還需要修改客戶端,否則單選按鈕無法應用于現(xiàn)有系統(tǒng)。

怎么辦?答案是抽象工廠模式無法解決該問題,這也是抽象工廠模式最大的缺點。在抽象工廠模式中,增加新的產(chǎn)品族很方便,但是增加新的產(chǎn)品等級結(jié)構(gòu)很麻煩,抽象工廠模式的這種性質(zhì)稱為“開閉原則”的傾斜性?!伴_閉原則”要求系統(tǒng)對擴展開放,對修改封閉,通過擴展達到增強其功能的目的,對于涉及到多個產(chǎn)品族與多個產(chǎn)品等級結(jié)構(gòu)的系統(tǒng),其功能增強包括兩方面:

(1) 增加產(chǎn)品族:對于增加新的產(chǎn)品族,抽象工廠模式很好地支持了“開閉原則”,只需要增加具體產(chǎn)品并對應增加一個新的具體工廠,對已有代碼無須做任何修改。

(2) 增加新的產(chǎn)品等級結(jié)構(gòu):對于增加新的產(chǎn)品等級結(jié)構(gòu),需要修改所有的工廠角色,包括抽象工廠類,在所有的工廠類中都需要增加生產(chǎn)新產(chǎn)品的方法,違背了“開閉原則”。

正因為抽象工廠模式存在“開閉原則”的傾斜性,它以一種傾斜的方式來滿足“開閉原則”,為增加新產(chǎn)品族提供方便,但不能為增加新產(chǎn)品結(jié)構(gòu)提供這樣的方便,因此要求設計人員在設計之初就能夠全面考慮,不會在設計完成之后向系統(tǒng)中增加新的產(chǎn)品等級結(jié)構(gòu),也不會刪除已有的產(chǎn)品等級結(jié)構(gòu),否則將會導致系統(tǒng)出現(xiàn)較大的修改,為后續(xù)維護工作帶來諸多麻煩。

抽象工廠模式總結(jié)

抽象工廠模式是工廠方法模式的進一步延伸,由于它提供了功能更為強大的工廠類并且具備較好的可擴展性,在軟件開發(fā)中得以廣泛應用,尤其是在一些框架和 API 類庫的設計中,例如在 Java 語言的 AWT(抽象窗口工具包)中就使用了抽象工廠模式,它使用抽象工廠模式來實現(xiàn)在不同的操作系統(tǒng)中應用程序呈現(xiàn)與所在操作系統(tǒng)一致的外觀界面。抽象工廠模式也是在軟件開發(fā)中最常用的設計模式之一。

主要優(yōu)點

抽象工廠模式的主要優(yōu)點如下:

(1) 抽象工廠模式隔離了具體類的生成,使得客戶并不需要知道什么被創(chuàng)建。由于這種隔離,更換一個具體工廠就變得相對容易,所有的具體工廠都實現(xiàn)了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實例,就可以在某種程度上改變整個軟件系統(tǒng)的行為。

(2) 當一個產(chǎn)品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產(chǎn)品族中的對象。

(3) 增加新的產(chǎn)品族很方便,無須修改已有系統(tǒng),符合“開閉原則”。

主要缺點

抽象工廠模式的主要缺點如下:

增加新的產(chǎn)品等級結(jié)構(gòu)麻煩,需要對原有系統(tǒng)進行較大的修改,甚至需要修改抽象層代碼,這顯然會帶來較大的不便,違背了“開閉原則”。

適用場景

在以下情況下可以考慮使用抽象工廠模式:

(1) 一個系統(tǒng)不應當依賴于產(chǎn)品類實例如何被創(chuàng)建、組合和表達的細節(jié),這對于所有類型的工廠模式都是很重要的,用戶無須關(guān)心對象的創(chuàng)建過程,將對象的創(chuàng)建和使用解耦。

(2) 系統(tǒng)中有多于一個的產(chǎn)品族,而每次只使用其中某一產(chǎn)品族??梢酝ㄟ^配置文件等方式來使得用戶可以動態(tài)改變產(chǎn)品族,也可以很方便地增加新的產(chǎn)品族。

(3) 屬于同一個產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設計中體現(xiàn)出來。同一個產(chǎn)品族中的產(chǎn)品可以是沒有任何關(guān)系的對象,但是它們都具有一些共同的約束,如同一操作系統(tǒng)下的按鈕和文本框,按鈕與文本框之間沒有直接關(guān)系,但它們都是屬于某一操作系統(tǒng)的,此時具有一個共同的約束條件:操作系統(tǒng)的類型。

(4) 產(chǎn)品等級結(jié)構(gòu)穩(wěn)定,設計完成之后,不會向系統(tǒng)中增加新的產(chǎn)品等級結(jié)構(gòu)或者刪除已有的產(chǎn)品等級結(jié)構(gòu)。

練習

Sunny 軟件公司欲推出一款新的手機游戲軟件,該軟件能夠支持 Symbian、Android 和 Windows Mobile 等多個智能手機操作系統(tǒng)平臺,針對不同的手機操作系統(tǒng),該游戲軟件提供了不同的游戲操作控制(OperationController)類和游戲界面控制(InterfaceController)類,并提供相應的工廠類來封裝這些類的初始化過程。軟件要求具有較好的擴展性以支持新的操作系統(tǒng)平臺,為了滿足上述需求,試采用抽象工廠模式對其進行設計。