面向對象設計模式

設計模式(Design Pattern)

概念:是一套被反覆使用(設計套路),多人知曉,經過分類編目的項目實踐活動中的經驗總結,是某一類典型問題的解決方案
來源:建築的設計模式(裝修房屋,和自已裝修對比)

簡單的講:所謂模式,就是得到很好研究的範例,設計模式就是設計範例。
模式不是框架,也不是過程,也不是簡單的問題解決方案,它必須是典型問題的解決方案,是可以讓學習者反覆使用,有研究價值和交流價值。

模式不能套用,不要以爲在任何一個系統中都要使用某些設計模式。系統的設計也不是含有設計模式越多就越好。

設計模式的本質是面向對象方法的實際運用。具體而言,是封裝,繼承和多態的反覆使用。可以說,現在市面上關於設計模式的書沒有一本適合初學者

要真正理解設計模式就需要透徹理解面向對象設計原則,和麪向對象三大特性。

設計原則

定義:指導面向對象編程的規範,通過遵守設計原則可以得到代碼更好的質量(可閱讀性,可維護性,可擴展新,和可測試性)

1)單一職責原則(SRP)

  • 不要存在多於一個導致類變更的原因。簡單的說,即一個類只負責一項職責
  • 不能爲圖代碼量少,把不同職責的類合併成一個類

2)開閉原則(OCP)

  • 對擴展開發,對修改關閉。
  • 主要是爲了向下兼容

3)依賴倒置原則(DIP)

  • 高層模塊不應該依賴底層模塊,二者都應該依賴於抽象;抽象不應該依賴於具體,具體應該依賴於抽象
  • 所謂的抽象就是定義接口
  • 接口和抽象類的區別:接口相當於一種協議(完全的抽象),抽象類:半抽象類(有數據,成員變量)
  • 總結:多用抽象的接口來描述相同的動作,降低實現類與類的耦合度,從而實現低耦合高內聚的最高原則。(一開始不應該寫具體的類,應該提取出公共的東西)

4 接口隔離原則(ISP)

  • 客戶端(接口的使用者)不應該依賴它不需要的接口;一個類對另一個類的依賴應該建立在最小的接口上。(只需要使用的接口)

5)迪米特原則(LKP):又叫最少接觸原則

  • 一個類對自已所依賴的類知道的越少越好,也就是說,對於被依賴的類來說無論邏輯多麼複雜,都儘量的將邏輯封裝在類的內部,對外處理提供public方法,不泄露任何信息。

6)里氏替換原則(LSP)

  • 子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法
  • 子類可以增加自已特點有的方法
  • 當子類的方法重寫父類的方法時,方法的前置條件(方法的參數)要比父類方法更寬鬆
  • 當子類的方法實現父類的抽象方法,方法的後置條件(方法的返回值)要比父類的方法更嚴格
  • 總結:用盡量不要重寫父類的已經實現的方法,可以接口等其他方法實現。

7)低耦合高內聚(最高原則)

UML(Unified Modeling Language)統一建模語言

概念:是目前面向對象軟件開發流行的用於分析和設計的標準建模語言
畫類圖的工具:EA

  1. 用例圖:用於分析用戶需求
  2. 靜態圖:用於顯示系統的靜態結構
  3. 類 圖:用於分析和設計類與類之間的關係
  4. 對象圖:用於分析和設計對象與對象之間的關係
  5. 序列圖:用於描述對象之間的交互順序
  6. 狀態圖:用於描述對象的所有狀態以及事件發生而引起的狀態之間的轉移
  7. 協作圖:用於描述對象之間的合作狀態,側重對象之間的消息傳遞
  8. 活動圖:用於描述用例要求所要進行的活動以及活動時間的約束關係
  9. 部署圖:用於描述系統中硬件的物理結構

類與類的關係

分類爲:縱向關係和橫向關係

縱向關係

  • 繼承關係,它的概念非常明確,也就是面向對象三大特性之一
  • UML表示法:實線+三角箭頭(箭頭指向的類爲父類)
  • 虛線+三角箭頭(箭頭指向的接口)

橫向關係

  1. 依賴關係:一個類依賴與另一個類,而另一個類並不依賴其他類,這種關係是一種偶然的,臨時的,非常弱在關係

    UML表示法:虛線+箭頭
    舉例:人依賴與空氣,但空氣並不依賴人
    
  2. 關聯關係:兩個類之間的一種長期的,平等的,可相互調用的關係。分爲單向和雙向的關係

    UML表示法:實線+箭頭
    舉例:朋友之間的關係
    
  3. 聚合關係:是關聯關係的一種特例,它體現的是整體和部分擁有的關係。整體和部分之間是分離的,各有各的生命週期。

    UML表示法:空心菱形(整體)+實線+箭頭(部分)
    舉例:班級和學員
    
  4. 組合關係:是關聯關係的一種特例,它體現的是整體和部分擁有的關係,整體和部分之間是不可分離的,整體的生命週期的結束意味着部分也結束。

    UML表示法:實心菱形(整體)+實線+箭頭(部分)
    舉例:人與心臟的關係
    

單列模式(Singleton模式)

1) 定義:是用於創建只有一個實例的類的解決方案

單列模式有兩種實現方式:懶漢式和餓漢式
餓漢式:天生支持線程安全
懶漢式:線程安全要加鎖(線程同步鎖synchronized)

特點:
    1.只能實例化一個對象
    2.單列類必須自已創建自已唯一實例化對象
    3.單列類必須給所有其他對象提供統一的對象獲取方法

2) 優點:

3) 缺點:

4) UML類圖怎麼畫:只有一個類(不用畫)

5) 使用場景:只需要一個類的實例

單例模式實現過程如下:

  • 首先,將該類的構造函數私有化(目的是禁止其他程序創建該類的對象);
  • 其次,在本類中自定義一個對象(既然禁止其他程序創建該類的對象,就要自己創建一個供程序使用,否則類就沒法用,更不是單例);
  • 最後,提供一個可訪問類自定義對象的類成員方法(對外提供該對象的訪問方式)。

直白的講就是,你不能用該類在其他地方創建對象,而是通過該類自身提供的方法訪問類中的那個自定義對象。

那麼問題的關鍵來了,程序調用類中方法只有兩種方式:

  • 創建類的一個對象,用該對象去調用類中方法;
  • 使用類名直接調用類中方法,格式“類名.方法名()”;

上面說了,構造函數私有化後第一種情況就不能用,只能使用第二種方法。
而使用類名直接調用類中方法,類中方法必須是靜態的,而靜態方法不能訪問非靜態成員變量,因此類自定義的實例變量也必須是靜態的。
這就是單例模式唯一實例必須設置爲靜態的原因。

工廠設計模式

定義:專門負責將大量有共同接口的類實例化;工廠模式可以動態決定將哪一個類實例化,不必事先知道每次要實例化的類

工廠模式有三種形態:

1)簡單工廠模式:又叫靜態工廠方法

2)工廠方法模式:又稱爲多態性工廠模式或虛擬構造子模式

3)抽象工廠模式:又稱工具箱模式

一: 簡單工廠模式:專門定義一個類來負責創建其他類的實例,被創建的類實例通常具有共同的父類

缺點:

  • 由於工廠類集中了所有產品的創建邏輯,一旦不能正常,整個系統都要受影響
  • 使用簡單工廠模式將會增加系統中類的個數,在一定程度上增加了系統複雜度,性能有所下降
  • 系統擴展困難,一旦添加新產品,就不得不修改工廠邏輯,在產品較多的時候,有可能造成工廠邏輯過於複雜,不利於系統的擴展和維護

優點:

  • 得到更好的可擴展性,可維護性
  • 工廠類還有必要的邏輯判斷,可以決定什麼時候創建哪一個產品,客戶端可以免除直接創建產品而僅僅使用產品就可以了
  • 客戶端無需知道所創建的具體產品類名,只需要知道具體產品對應的參數即可,對於一些複雜的類名通過簡單工廠模式可以減少使用者的記憶量

適用場景:

  • 工廠類負責創建的對象比較少;由於創建的對象比較少就不會造成工廠方法中的業務邏輯太過複雜
  • 客戶端只知道傳入工廠類的參數,對象如何創建對象不關心;客戶端既不需要管線創建細節,甚至連類名都不需要知道。

二: 工廠方法模式

定義:一個用於創建對象的接口或者是抽象類,讓子類決定實例化哪一個類。工廠方法使用一個類的實例延遲到其子類。

優點:

  • 在工廠方法中,客戶端只需要知道產品工廠類即可,不需要知道具體的產品類。
  • 基於工廠類的多態性設計,是工廠方法模式的關鍵;它能夠使工廠可以自主確定創建何種產品對象,而如何創建產品細節則完全封裝到具體工廠內部。工廠方法模式之所以又稱爲多態工廠模式,正是因爲所以的具體工廠類都具有同一個抽象工廠類。
  • 使用工廠方法模式在系統中加入新產品時,無需修改抽象工廠類,也無需修改客戶端,也無需修改其他的具體工廠類和具體產品,而只需要添加具體工廠類和具體產品類,這樣系統的可擴展性也就變得非常好,完全符合“開閉原則”

缺點:

  • 在添加新產品是需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將增加兩個類(成對增加),在一定程度上增加了系統的複雜度,會給系統帶來額外的開銷(降低了性能)

使用場景

  • 工廠類負責創建的對象比較多,由於具有很好的擴展性,對系統的影響較小

三:抽象工廠模式

定義:提供一個創建一系列或相互依賴的對象接口,而無需指定它們的具體類

優點:

  • 隔離了具體類的創建,使得客戶端不需要知道具體產品類
  • 當一個產品族中的多個對象被設計一起工作時,它能夠保證客戶端始終只使用同一個產品族中的對象,也就是我們的工廠沒變

缺點:

  • 添加新產品對象時,難以擴展抽象工廠以便生產新種類產品

使用場景

  • 一個系統的產品族有多於一個產品族,而系統只使用其他某一個產品族的產品
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章