前言
設計模式最初是在上個世紀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種設計模式分爲三個大類:創建型模式、結構型模式、行爲型模式。每個大類的關注點和所包含的設計模式類型如下圖所示: