1 簡單工廠模式(Static Factory Method)
適用場景
- 工廠類負責創建的對象比較少。
- 客戶只知道傳入工廠類的參數,對於如何創建對象(邏輯)不關心。
- 由於簡單工廠很容易違反高內聚責任分配原則,因此一般只在很簡單的情況下應用。
優點
- 工廠類是整個模式的關鍵。包含了必要的邏輯判斷,根據外界給定的信息,決定究竟應該創建哪個具體類的對象。
- 通過使用工廠類,外界可以從直接創建具體產品對象的尷尬局面擺脫出來,僅僅需要負責“消費”對象就可以了。而不必管這些對象究竟如何創建及如何組織的。明確了各自的職責和權利,有利於整個軟件體系結構的優化。
缺點
- 由於工廠類集中了所有實例的創建邏輯,違反了高內聚責任分配原則,將全部創建邏輯集中到了一個工廠類中,它所能創建的類只能是事先考慮到的,如果需要添加新的類,則就需要改變工廠類了。
- 當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不同條件創建不同實例的需求。這種對條件的判斷和對具體產品類型的判斷交錯在一起,很難避免模塊功能的蔓延,對系統的維護和擴展非常不利。
- 這些缺點在工廠方法模式中得到了一定的克服。
2 策略模式(Strategy)
適用場景
- 多個類有不同的表現形式,每種表現形式可以獨立成單獨的算法。
- 需要再不同情況下使用不同的算法,以后算法可能還會增加。
- 對用戶隱藏算法邏輯。
優點
- 每個算法單獨封裝,減少了算法和算法調用者的耦合。
- 合理使用繼承有助於提取出算法中的公共部分。
- 簡化了單元測試。
缺點
- 策略模式只適用於客戶端知道所有的算法或行為的情況。
- 策略模式造成很多的策略類,每個具體策略類都會產生一個新類。不過可以使用享元模式來減少對象的數量。
3 裝飾模式(Decorator)
適用場景
- 需要擴展一個類的功能,或給一個類添加附加職責。
- 需要動態的給一個對象添加功能,這些功能可以再動態的撤銷。
- 需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關系變的不現實。
- 當不能采用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用於生成子類。
優點
- Decorator模式與繼承關系的目的都是要擴展對象的功能,但是Decorator可以提供比繼承更多的靈活性。
- 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行為的組合。
缺點
- 這種比繼承更加靈活機動的特性,也同時意味着更加多的復雜性。
- 裝飾模式會導致設計中出現許多小類,如果過度使用,會使程序變得很復雜。
- 裝飾模式是針對抽象組件(Component)類型編程。但是,如果你要針對具體組件編程時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component接口,增加新的公開的行為,實現“半透明”的裝飾者模式。在實際項目中要做出最佳選擇。
4 代理模式(Proxy)
適用場景
- 遠程代理,為一個對象在不同的地址空間提供局部代表,這樣就可以隱藏一個對象存在於不同地址空間的事實。
- 虛擬代理,是根據需要創建開銷很大的對象。通過它來存放實例化需要很長時間的真是對象。
- 安全代理,用來控制真實對象訪問時的權限。
- 智能指引,是指當調用真是的對象時,代理處理另外的一些事情。
優點
- 職責清晰,真實的角色就是實現實際的業務邏輯,不用關心其他非本職責的事務,通過后期的代理完成一件完成事務,附帶的結果就是編程簡潔清晰。
- 代理對象可以在客戶端和目標對象之間起到中介的作用,這樣起到了中介的作用和保護了目標對象的作用。
- 高擴展性
缺點
- 在客戶端和目標對象增加一個代理對象,會造成請求處理速度變慢。
- 增加了系統的復雜度。
5 工廠方法模式(Factory Method)
適用場景
- 工廠方法模式是new一個對象的替代品,所以在所有需要生成對象的地方都可以使用,但是需要慎重地考慮是否要增加一個工廠類進行管理,增加代碼的復雜度。
- 需要靈活的、可擴展的框架時,可以考慮采用工廠方法模式。
- 工廠方法模式可以用在異構項目中,例如通過WebService與一個非Java的項目交互,雖然WebService號稱是可以做到異構系統的同構化,但是在實際的開發中,還是會碰到很多問題,如類型問題、WSDL文件的支持問題,等等,從WSDL中產生的對象都認為是一個產品,然后由一個具體的工廠類進行管理,減少與外圍系統的耦合。
- 可以使用在測試驅動開發的框架下,例如,測試一個類A,就需要把與類A有關聯關系的類B也同時產生出來,我們可以使用工廠方法模式把類B虛擬出來,避免類A與類B的耦合。目前由於JMock和EasyMock的誕生,該使用場景已經弱化了,讀者可以在遇到此種情況時直接考慮使用JMock或EasyMock。
優點
- 良好的封裝性,代碼結構清晰,減少模塊間的耦合。
- 工廠方法模式的擴展性非常優秀。
- 屏蔽產品類。
- 工廠方法模式是典型的解耦框架。
缺點
- 使用者必須知道相應工廠的存在。
- 每次增加一個產品時,都需要增加一個具體類和對象實現工廠,是的系統中類的個數成倍增加,在一定程度上增加了系統的復雜度,同時也增加了系統具體類的依賴。
6 原型模式(Prototype)
適用場景
- 某些結構復雜的對象的創建工作;由於需求的變化,這些對象經常面臨着劇烈的變化,但是他們卻擁有比較穩定一致的接口。
- 一般在初始化的信息不發生變化的情況下,克隆是最好的方法。
優點
- 隱藏了對象創建的細節。
- 提高了性能。
- 不用重新初始化,動態獲得對象運行時的狀態。
缺點
- 適用性不是很廣。
- 每一個類必須配備一個克隆方法。
- 配備克隆方法需要對類的功能進行通盤考慮,這對於全新的類不是很難,但對於已有的類不一定很容易,特別當一個類引用不支持串行化的間接對象,或者引用含有循環結構的時候。
7 模板方法模式(Template Method)
適用場景
- 適用於子類中有重復的代碼,可以把重復代碼提取出來,放到父類中。
優點
- 提高代碼復用性。
- 幫助子類擺脫重復的不變行為。
缺點
- 考慮不全面統一出現問題。