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