前言
設計模式最初是在上個世紀70年代在建築領域提出來,一些建築大師們在總結解決各種建築問題時提出了上百種對應的解決模式。後來逐漸被引入到軟體領域,起初並沒有引起太大的關注,直到有4個人(Gong Of Four,業界稱呼他們為“四人幫")合作出版了一本叫做《設計模式:可複用物件導向軟體基礎》的書,在業界產生了強烈的反響,從此以後設計模式被廣泛地應用於軟體領域。
設計模式在面試和實際開發中,尤其是架構設計中佔據著很重要的地位,本系列文章是筆者系統學習設計模式的學習筆記,總結了設計模式的知識框架和知識要點,以便複習之用。本篇主要包含了如下內容:
一、類圖的基本畫法
1、類圖中修飾符的基本表示
上面類圖中左邊的特殊符號所表示的含義為:
+:public -: private #: protected ~: default 下劃線: static 斜體: abstract
- 屬性的完整表示方法:可見性 名稱 :型別 [ = 預設值 ]
- 方法的完整表示方法:可見性 名稱(引數列表) [ : 返回型別 ]
如果用java語言實現,那麼上述類圖對應的類結構如下:
1 public abstract class Student { 2 public String name = "Zhang San"; 3 private int score = 100; 4 protected String id; 5 String address; 6 public static String sex = ""; 7 8 public void setName(String name) { 9 10 } 11 12 protected String getId() { 13 return ""; 14 } 15 16 public abstract void jump(); 17 }
2、類與類之間常見的關係
類與類之間的關係,比較常見的有6種,其關聯程由弱到強的順序依次為:依賴關係 < 關聯關係 < 聚合關係 < 組合關係 < 繼承關係 < 實現關係,下面一一介紹這些關係。
(1)泛化關係(Generalization)
即繼承關係,描述子類與父類之間的繼承關係,是is-a的關係。其包括類對類的繼承,介面對介面的繼承,在java中使用 extends 關鍵字。
其表示方法為:實線 + 空心三角
泛化關係的類圖表示示例:
(2)實現關係(Realization)
表示實現類與介面之間的實現關係,在java中使用 implements關鍵字,和泛化關係一樣,也是is-a的關係。
其表示方法為:虛線 + 空心三角
實現關係的類圖表示示例:
(3)關聯關係(Association)
關聯關係是類與類之間最常用的一種關係,是一種結構化的引用關係,用於表示一個類物件與另一個類物件之間有聯絡,在程式碼中通常將一個類的物件作為另一個類的成員變數來實現關聯關係。關聯關係根據關聯的強弱程度,由弱到強的順序可以分為一般關聯關係、聚合關係、組合關係,可以統一表示為has-a關係。這裡關聯關係沒有做特別說明,指的是一般關聯關係。
其表示方法為:實線 + 箭頭 ,並可以在上面標註數量關係;
一般關聯關係又有四種情況:1)雙向關聯;2)單向關聯;3)自關聯;4)多重數關聯。
1)雙向關聯
丈夫和妻子的關係就是相互的,丈夫擁有了妻子,那妻子就擁有了丈夫,在中國他們的關係只能是互相擁有一個。雙向關係可以用雙向箭頭,也可以用沒有箭頭的直線表示。
2)單向關係
3)自關聯
在系統中可能會存在一些類的屬性物件型別為該類本身,這種特殊的關聯關係稱為自關聯,比如定義二叉樹的節點。
1..1
:僅一個0..*
:零個或多個1..*
:一個或多個0..1
:沒有或只有一個m..n
:最少m、最多n個 (m<=n)
(4)聚合關係(Aggregation)
描述一種較弱的整體與部分關係,整體與部分之間可以分割,部分脫離整體後可以獨立存在,比如魚與魚群的關係,魚離開了魚群也可以單獨存在,是一種own-a的關係,整體與部分可以存在1對多的關係。
其表示方法為:空心菱形 + 實線,菱形端指向整體。
組合關係的類圖表示示例:
(5)組合關係(Composition)
描述一種較強的整體與部分關係,整體與部分之間不可以分割,部分脫離整體後不可以獨立存在,比如翅膀與鳥的關係,翅膀不可以脫離鳥而單獨存在,是一種is-a-part-of關係,整體與部分可以存在1對多的關係。
其表示方法為:實心菱形 + 實線,菱形端指向整體。
組合關係的類圖表示示例:
(6)依賴關係(Dependency)
依賴關係是一種使用關係,它是物件之間耦合度最弱的一種關聯方式,是臨時性的關聯。在程式碼中,某個類的方法通過區域性變數、方法的引數或者對靜態方法的呼叫來訪問另一個類(被依賴類)中的某些方法來完成一些職責。
其表示方法為:虛線 + 箭頭箭頭從使用類指向被依賴的類。
依賴關係的類圖表示示例:
為了方便記憶這6個關係,這裡做一個簡單對對比和歸納:
二、設計模式的七個原則
設計模式的設計包含了如下七個原則(有的資料說是六種,這裡我們們以七種為準):
1、開閉原則:
Open Close Principle,意思是對擴充套件開放,對修改關閉。在程式需要進行擴充的時候,不能去修改原有的程式碼,實現一個熱插拔的效果。簡言之,是為了使程式的擴充套件性好,易於維護和升級。想要達到這樣的效果,我們需要使用介面和抽象類。
2、依賴倒轉原則
Dependency Inversion Principle,是開閉原則的基礎,具體內容為:面向介面程式設計,依賴抽象而不依賴具體。
3、單一職能原則
Single Responsibility Principle,意思是,就一個類而言,應該只包含一個職責,增強內聚性,降低耦合度。這裡的職責是指類變化的原因,單一職責原則規定一個類應該有且僅有一個引起它變化的原因,否則類應該被拆分。
4、介面隔離原則
Interface Segregation Principle,意思是,使用多個相互隔離的介面,比使用單個介面好。其作用為降低類與類之間的耦合度。
5、迪米特原則
Demeter Principle,也叫最少知道原則,它表示實體與實體之間應該儘量減少互動,保持模組與模組之間相互獨立。
6、里氏代換原則
Liskov Substitution Principle,其含義是,任何基類可以出現的地方,子類也一定可以出現。只有當派生類可以替換掉基類,且軟體單位的功能不受到影響時,基類才能真正被複用,而派生類也能夠在基類的基礎上增加新的行為。
7、合成複用原則
Composition Reuse Principle,儘量使用合成/聚合的方式,而不是使用繼承。
三、設計模式中不可不知的物件導向知識要點
1、抽象類與介面的異同點
介面(Interface)與抽象類(Abstract Class)的區別
2、多型(重寫與過載)
四、23種設計模式及它們之間的關係
下圖來源於Gof的《設計模式 - 可複用物件導向軟體基礎》,列舉了這23種設計模式以及它們之間的關係(這個圖我沒怎麼看懂,留在這裡經常來觀摩觀摩)。
五、設計模式的分類
《設計模式 - 可複用物件導向軟體基礎》將這23種設計模式分為三個大類:建立型模式、結構型模式、行為型模式。每個大類的關注點和所包含的設計模式型別如下圖所示: