什麼是設計模式?為什麼要使用設計模式?有什麼好處?

風靈使發表於2019-04-14

設計模式(Design pattern):是針對設計問題的通用解決方案。

使用設計模式:可以把它應用到特定的應用中,用於解決相似的問題。

使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。

真正理解什麼是設計模式,就是要透徹理解OO的四大要素:封裝、繼承、多型和關聯。其中核心是封裝的概念。


常用設計模式的一些優缺點

1 簡單工廠模式(Static Factory Method

適用場景

工廠類負責建立的物件比較少。
客戶只知道傳入工廠類的引數,對於如何建立物件(邏輯)不關心。
由於簡單工廠很容易違反高內聚責任分配原則,因此一般只在很簡單的情況下應用。

優點

工廠類是整個模式的關鍵。包含了必要的邏輯判斷,根據外界給定的資訊,決定究竟應該建立哪個具體類的物件。

通過使用工廠類,外界可以從直接建立具體產品物件的尷尬局面擺脫出來,僅僅需要負責“消費”物件就可以了。而不必管這些物件究竟如何建立及如何組織的。明確了各自的職責和權利,有利於整個軟體體系結構的優化。

缺點

  1. 由於工廠類集中了所有例項的建立邏輯,違反了高內聚責任分配原則,將全部建立邏輯集中到了一個工廠類中,它所能建立的類只能是事先考慮到的,如果需要新增新的類,則就需要改變工廠類了。
  2. 當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不同條件建立不同例項的需求。這種對條件的判斷和對具體產品型別的判斷交錯在一起,很難避免模組功能的蔓延,對系統的維護和擴充套件非常不利。
  3. 這些缺點在工廠方法模式中得到了一定的克服。

2 策略模式(Strategy

適用場景

  1. 多個類有不同的表現形式,每種表現形式可以獨立成單獨的演算法。
  2. 需要再不同情況下使用不同的演算法,以後演算法可能還會增加。
  3. 對使用者隱藏演算法邏輯。

優點

  1. 每個演算法單獨封裝,減少了演算法和演算法呼叫者的耦合。
  2. 合理使用繼承有助於提取出演算法中的公共部分。
  3. 簡化了單元測試。

缺點

  1. 策略模式只適用於客戶端知道所有的演算法或行為的情況。
  2. 策略模式造成很多的策略類,每個具體策略類都會產生一個新類。不過可以使用享元模式來減少物件的數量。

3 裝飾模式(Decorator

適用場景

  1. 需要擴充套件一個類的功能,或給一個類新增附加職責。
  2. 需要動態的給一個物件新增功能,這些功能可以再動態的撤銷。
  3. 需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關係變的不現實。
  4. 當不能採用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴充套件,為支援每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用於生成子類。

優點

  1. Decorator模式與繼承關係的目的都是要擴充套件物件的功能,但是Decorator可以提供比繼承更多的靈活性。
  2. 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行為的組合。

缺點

  1. 這種比繼承更加靈活機動的特性,也同時意味著更加多的複雜性。
  2. 裝飾模式會導致設計中出現許多小類,如果過度使用,會使程式變得很複雜。
  3. 裝飾模式是針對抽象元件(Component)型別程式設計。但是,如果你要針對具體元件程式設計時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component介面,增加新的公開的行為,實現“半透明”的裝飾者模式。在實際專案中要做出最佳選擇。

4 代理模式(Proxy

適用場景

  1. 遠端代理,為一個物件在不同的地址空間提供區域性代表,這樣就可以隱藏一個物件存在於不同地址空間的事實。
  2. 虛擬代理,是根據需要建立開銷很大的物件。通過它來存放例項化需要很長時間的真是物件。
  3. 安全代理,用來控制真實物件訪問時的許可權。
  4. 智慧指引,是指當呼叫真是的物件時,代理處理另外的一些事情。

優點

  1. 職責清晰,真實的角色就是實現實際的業務邏輯,不用關心其他非本職責的事務,通過後期的代理完成一件完成事務,附帶的結果就是程式設計簡潔清晰。
  2. 代理物件可以在客戶端和目標物件之間起到中介的作用,這樣起到了中介的作用和保護了目標物件的作用。
  3. 高擴充套件性

缺點

  1. 在客戶端和目標物件增加一個代理物件,會造成請求處理速度變慢。
  2. 增加了系統的複雜度。

5 工廠方法模式(Factory Method

適用場景

  1. 工廠方法模式是new一個物件的替代品,所以在所有需要生成物件的地方都可以使用,但是需要慎重地考慮是否要增加一個工廠類進行管理,增加程式碼的複雜度。
  2. 需要靈活的、可擴充套件的框架時,可以考慮採用工廠方法模式。
  3. 工廠方法模式可以用在異構專案中,例如通過WebService與一個非Java的專案互動,雖然WebService號稱是可以做到異構系統的同構化,但是在實際的開發中,還是會碰到很多問題,如型別問題、WSDL檔案的支援問題,等等,從WSDL中產生的物件都認為是一個產品,然後由一個具體的工廠類進行管理,減少與外圍系統的耦合。
  4. 可以使用在測試驅動開發的框架下,例如,測試一個類A,就需要把與類A有關聯關係的類B也同時產生出來,我們可以使用工廠方法模式把類B虛擬出來,避免類A與類B的耦合。目前由於JMockEasyMock的誕生,該使用場景已經弱化了,讀者可以在遇到此種情況時直接考慮使用JMock或EasyMock。

優點

  1. 良好的封裝性,程式碼結構清晰,減少模組間的耦合。
  2. 工廠方法模式的擴充套件性非常優秀。
  3. 遮蔽產品類。
  4. 工廠方法模式是典型的解耦框架。

缺點

  1. 使用者必須知道相應工廠的存在。
  2. 每次增加一個產品時,都需要增加一個具體類和物件實現工廠,是的系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。

6 原型模式(Prototype

適用場景

  1. 某些結構複雜的物件的建立工作;由於需求的變化,這些物件經常面臨著劇烈的變化,但是他們卻擁有比較穩定一致的介面。
  2. 一般在初始化的資訊不發生變化的情況下,克隆是最好的方法。

優點

  1. 隱藏了物件建立的細節。
  2. 提高了效能。
  3. 不用重新初始化,動態獲得物件執行時的狀態。

缺點

  1. 適用性不是很廣。
  2. 每一個類必須配備一個克隆方法。
  3. 配備克隆方法需要對類的功能進行通盤考慮,這對於全新的類不是很難,但對於已有的類不一定很容易,特別當一個類引用不支援序列化的間接物件,或者引用含有迴圈結構的時候。

7 模板方法模式(Template Method

適用場景

  1. 適用於子類中有重複的程式碼,可以把重複程式碼提取出來,放到父類中。

優點

  1. 提高程式碼複用性。
  2. 幫助子類擺脫重複的不變行為。

缺點

  1. 考慮不全面統一出現問題。

好處

重用性

擴充套件性

靈活性

結構型設計模式:鬆耦合

避免了客戶端環境與產品物件複雜的構造邏輯耦合

相關文章