從類別圖了解類別之間的依賴關係
物件導向程式設計,是在設計一個系統--用到多少類別,以及類別之間的關係。
類別圖(class diagram)可以用圖例的方法呈現類別之間的關係,正所謂一圖勝萬言,使用圖例表達類別的關係,比直接看程式碼來的清楚很多;因為類別圖很常用,所以學習物件導向程式設計,至少要懂得看類別圖。
以下使用 PlantUML 作為畫圖的工具
首先先看單一類別是如何呈現資訊:
@startuml |
一個類別可以分作四個部分:
- 類型,比方說是介面(interface)或類別(class),上例為類別
- 名稱,上例為
Person
- 屬性(property)
- 方法(method)
其中屬性和方法會有不同的能見度。而能見度的表示方法如下:
+
public-
private#
protected~
package
了解單一類別的表示法,再來是了解類別之間關係。類別圖定義了六種關係,以下為簡單的說明。
依賴(Dependency)
類別間的依賴,表示了 A 類別使用了 B 類別,如下圖:
@startuml |
在程式上的意義,指的是 A 類別的方法定義裡,有 B 類別。比方說,Person 類別使用信用卡買 Switch,用 PHP 程式語言表達的方法如下:
class Person { |
對應的類別圖如下:
@startuml |
這個程式寫法很常出現在靜態方法上。
關聯(Association)
關聯表示的是 A 類別擁有 B 類別,如下圖:
@startuml |
程式上的意義,指的就是類別的屬性,比方說 Person 類別有 cellphone 屬性是 Cellphone 類別。PHP 程式語言表達的方法如下:
class Person { |
對應的類別圖如下:
@startuml |
聚合(Aggregation)
聚合表示的關係是 A 類別包含了 B 類別,如下圖:
@startuml |
程式上的意義有下面幾個:
- A 類別的屬性有 B 類別
- A 類別的方法會用到 B 的屬性
- A 類別與 B 類別的生命週期是各自獨立的,比方說 B 類別產生的物件可同時被另一個 A 類別產生的物件聚合。
第三點可能有點抽象,舉個實例:如 Switch 與 JoyCon 的關係就是一個聚合最佳實例,JoyCon 不限定用在哪台主機,只要是 Switch,裝上去都能正常操作。而且兩者生命週期是各自獨立的,JoyCon 壞了可以買新的裝上;Switch 主機壞了,JoyCon 可以留到下一台主機繼續用。
畫成類別圖如下:
@startuml |
組合(Composition)
組合代表的意義為,B 類別為 A 類別的一部分,如下圖
@startuml |
與聚合的條件類似,唯獨第三點不同:A 類別與 B 類別的生命週期是一致的,也就是要嘛一起產生,要嘛一起死。
實務上來說,Macbook 與記憶體(Memory)的關係即為組合:如果一個壞,另一個也難逃一死。而過去較舊的機型則是聚合,因為可以抽換。
畫成類別圖如下:
@startuml |
實作(Realization)與繼承(Generalization)就不特別說明,因為跟物件導向討論的大同小異,對應的圖如下:
實作:
@startuml |
繼承:
@startuml |
小結
一共有六種關係,下面是一個關係由弱到強的表格
關係 | 描述 |
---|---|
依賴 | A use a B |
關聯 | A has a B |
聚合 | A owns a B |
組合 | B is part of A |
實作 | B implement A |
繼承 | B extends A |
越弱的關係,在修改 B 的程式碼,影響 A 的風險就越小。
了解類別圖與這個比較表的目的有兩個:
- 這是共同語言(UML)。
- 知道有不同的關係後,才知道如何比較不同的程式碼,進而達到改善的目的。