UML类图最生动的介绍和例子
目的
這篇文章主要是介紹如何使用UML類圖,目的是讓我們能讀懂類圖,以及上手使用類圖。
為什么要使用UML類圖
UML類圖是一種統一建模語言,可以精準的描述類中擁有的屬性以及方法,以及類與類之間的關系。
它能夠非常直觀的,通過可視化的方式展示一系列相關類之間的交互關系。
在學習設計模式,或者設計自己的類結構時,大都通過UML類圖的形式進行展示。
類圖的組成
類圖的組成非常很簡單,只有類 和 類之間的關系 組成。
類
描述了類內部的內容。其中包括類的屬性和類的方法,以及他們的可見性。類之間的關系
描述了類與類之間的交互的方式,包括泛化、實現、依賴、關聯、聚合、組合。那么我們先來看一下關于類的部分UML是如何描述的,下面是一個例子
上圖描述了一個商品(product)類
首先我們看到這個圖的第一部分
該部分描述了這個類的名稱,以及它是類型是 類(class)、抽象類(abstract class)還是接口(interface)。
類由C字面表示,抽象類由A表示,接口用I表示。
第二部分描述了類中包含的屬性,屬性的類型以及可見度
屬性可見度+屬性名稱+冒號+屬性類型,這是UML類圖描述屬性的基本格式。
該例子中,商品(product)類有三個屬性,分別是名稱(name)、價格(price)和stock(庫存)。
名稱是String類型的,其余的都是int類型。三個屬性全部為私有字段。
可見度
關于可見度有必要說明一下,首先類中的屬性和方法每個都可以設置不同的可見度,比如私有的(private)和公共的(public)。在UML類圖中的表述方式有直接通過加(+)減(-)表示的,也有通過圖標的形式表示的。
因為我們的例子使用的是PlantUML工具實現的,所以把該工具表示可見性的規則放在這里:
下面我們來看類的第三部分
該部分描述類中的方法,相信這部分理解應該問題不大
類圖描述方法的格式為:方法可見度+方法名稱+方法入參
在例子中,我們提供了三個屬性的get方法,以及減庫存(reductionStock)方法,它的入參是一個整形,入參名稱為數量(num)。它們的可見度均為公共的(public)
那么上述就是關于類圖中類的描述
類之間的關系
類之間的關系稍微復雜一些,包含泛化、實現、依賴、關聯、聚合、組合。
但實際上這些組合方式我們在代碼開發過程中經常使用
我們會成對的介紹它們,并且提供實例,方便理解
如果你對上述關系已經很了解了,可以直接跳到實例閱讀,否則建議先了解這些關系的含義
泛化與實現
泛化就是我們常常講到的繼承(extends),是指我們對類或抽象類的繼承
實現(implements)比較好理解,是指一個類對接口的實現。
依賴、關聯、聚合、組合
這個四種關聯關系比較難以區分,我們讀一段《Java面向對象編程》對其的定義
概念可能比較多,比較抽象,后面我們會舉例子來解釋
在這里我們只需要明確,這四種關聯關系是層層遞進的,耦合度越來越高就可以了。
-
依賴(Dependency)
依賴關系是類與類之間的聯接。依賴關系表示一個類依賴于另一個類的定義。依賴關系在Java語言中體現為局域變量、方法的形參,或者對靜態方法的調用。 -
關聯(Association)
依賴關聯關系是類與類之間的聯接,它使一個類知道另一個類的屬性和方法。關聯可以是雙向的,也可以是單向的。在Java語言中,關聯關系一般使用成員變量來實現。 -
聚合(Aggregation)
聚合關系是關聯關系的一種,是強的關聯關系。聚合是整體和個體之間的關系。例如,汽車類與引擎類、輪胎類,以及其它的零件類之間的關系便整體和個體的關系。與關聯關系一樣,聚合關系也是通過實例變量實現的。但是關聯關系所涉及的兩個類是處在同一層次上的,而在聚合關系中,兩個類是處在不平等層次上的,一個代表整體,另一個代表部分。 -
組合(Composition)
組合關系是關聯關系的一種,是比聚合關系強的關系。它要求普通的聚合關系中代表整體的對象負責代表部分對象的生命周期,組合關系是不能共享的。代表整體的對象需要負責保持部分對象和存活,在一些情況下將負責代表部分的對象湮滅掉。代表整體的對象可以將代表部分的對象傳遞給另一個對象,由后者負責此對象的生命周期。換言之,代表部分的對象在每一個時刻只能與一個對象發生組合關系,由后者排他地負責生命周期。部分和整體的生命周期一樣。
——摘自《Java面向對象編程》,作者:孫衛琴
類關系的實例
OK那么我們接下來逐個解釋
1. 泛化
泛化符號是以三角箭頭以及實線組成
該例子中,狗(dog)類繼承了動物類(animal)
實現代碼
class main{class animal {public void move(){print("move")}}class dog extends animal {public void bark(){print("wangwangwagn")}} }2. 實現
泛化符號是以三角箭頭以及虛線組成
該例子中,汽車類(car)實現了運輸接口(Transport)
實現代碼
class Main{interface Transport{void deliver();}class Car implements Transport{public void deliver(){print("deliver to destination")}} }3. 依賴
依賴關系表示一個類依賴于另一個類的定義,即一個類的實現需要另一個類的協助。依賴關系通常是局部的,在程序中的體現往往是A類的某個方法需要傳入一個B類,或者A類在某個方法中創建了B類局部變量。
依賴是通過箭頭+虛線表示的
在該例子中,我們有一個人(People)類,它有兩個方法打獵(hunting)和吃飯(eat)。
其中打獵方法調用時需要傳入槍(Gun)類,吃飯方法調用時需要傳入食物(Food)類。
此時,人(People)類就是的實現就依賴于槍(Gun)和食物(Food)類。
代碼實現
class Main{class Gun{public void get(){print("這是一把槍!"); }}class Food{public void get(){print("這是一份食物!"); }}class People{public void hunting(Gun gun){gun.get();print("獲取槍支,開始打獵!");}public void eat(Food food){food.get();print("獲取食物,開始吃飯!");}}}4. 關聯
關聯關系比依賴關系更近一步,它使一個類知道另一個類的屬性和方法。
在代碼的體現上通常是作為類中的成員變量存在。
關聯是通過箭頭+實線表示的
在該例子中,我們擁有警察類(Police)和槍(Gun)類
警察類通過成員變量gun與槍類進行關聯
警察在調用waring()和shooting()方法時使用了gun。
區別
這里需要注意的是與上一個例子的區別
這兩個例子中都存在槍(Gun)類,但不同的是警察在是一直要佩戴槍支的
而普通人只有在打獵場景時(對應調用hunting()方法時)才需要槍
普通人與槍的關系時依賴關系
而警察與槍的關系時關聯
代碼實現
class Main{class Gun{public void show(){print("展示槍支")}public void shooting(){print("發射子彈!")}}class Police{private Gun gun;public setGun(gun){this.gun = gun;}//警察通過持槍警告罪犯public void waring(){gun.show()print("不許動!")}//警察使用槍支進行射擊public void shooting(){gun.shooting()}}}5. 聚合
聚合關系是關聯關系的一種,是強的關聯關系。聚合強調的是對象之前整體與部分的依賴關系。
與關聯關系一樣,聚合關系也是通過實例變量實現的。但是關聯關系所涉及的兩個類是處在同一層次上的,而在聚合關系中,兩個類是處在不平等層次上的,一個代表整體,另一個代表部分
聚合是通過空心菱形+實線表示的
該例子中,汽車(Car)類與引擎(Engine)類屬于聚合的關系
其中Engine屬于Car的一部分,雙方的關系不是對等的關系
代碼實現
class Main{public class Engine{public void on(){print("引擎啟動");}}public class Car{Engine engine;void setEngine(Engine engine){this.engine = engine;}public void show(){engine.show();pring("開車去兜風");}}void Main(){Car car = new Car();car.setEngine(new Engine());car.show();}}6. 組合
組合關系又是聚合關系的加強
其中組合關系強調的是整體對象負責管理部分對象的生命周期
而且在整個過程中,代表部分的對象應只屬于一個整體對象。
組合是通過實心菱形+實線表示的
該例子中,學校(School)類與班級(Classes)類屬于組合的關系
學校構建了所有的班級集合,并管理它們的生命周期。
而班級只屬于某所學校,在整個生命周期中,除非有必要(在本實例中沒有這個必要),否則學校類甚至可以不暴露任何有關班級的實體。
也就是說,學校類可以擁有對班級類完整的控制權。
代碼實現
class Main{public class School{private Stirng name;private List<Classes> classesList;public School(int sumClasses){classesList = ArrayList<>();for(int i = 0 ; i < sumClasses ; i ++){classesList.add(new Classes(sumClasses+"班級"));}}public void giveLessons(){print("上課啦!");for(Classes Classes : classesList){Classes.giveLessons();}}}public class Classes{private Stirng name;public Classes (String name){this.name = name;}public void giveLessons(){print(name+"班上課啦!");}}void Main(){new School().giveLessons();}}畫圖軟件
簡單的介紹一款畫圖軟件,叫PlantUML
這個軟件的優點是通過簡單的代碼就能生成UML圖,而且支持中文,官網有很多詳細的使用方法和例子
對比較熟悉代碼的朋友們來說,這個畫圖軟件還是比較好用的(其實都不應該叫畫圖軟件了lol)
但是如果是對代碼不是很理解,或者不能很方便的用代碼作為生產力的同學
還是建議根據自己的系統平臺找一找別的畫圖軟件,這里就不展開了
結語
OK那么關于UML類圖的介紹就到這里了。這篇文章斷斷續續寫了蠻久,主要是因為個人原因,一直覺得有些例子沒有很好的詮釋這些關系中的區別,但是一耽擱就幾個月沒再動筆了。
這篇文章的目的主要是想通過比較簡單的語言加上例子,讓大家對這些關系有一個比較清楚的認識。
如果覺得文章中有錯誤的地方請及時指正,謝謝!
總結
以上是生活随笔為你收集整理的UML类图最生动的介绍和例子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt程序移植
- 下一篇: pc 装MAC 资料