UML類圖精煉及其最佳實踐
田海立@CSDN 2020-10-08
UML(Unified Modeling Language)的各種圖中類圖(Class Diagram)是基礎,描述一個系統可以從不同視角去看,這些不同視角的圖聚合在一起,才能比較完整地闡述系統。本文描述類圖的基本概念——各種類元和它們之間的關係,並結合實際工作經驗探討了描述類圖時的最佳實踐。
UML中的類圖描述的是什麼,最基本的問題也才最關鍵,有些時候真的可能是做了很長時間的事,基本的概念都還沒搞清楚。類圖描述的類(介面)的組成和行為、以及這些類組合在一起後它們之間的關係。這是一種靜態關係,所以一般的著作中會把它歸類到靜態圖裡。
一、UML類圖
1.1 類圖中的類/介面
1) 類
類是有著相同結構、行為和關係的一組物件的抽象,在幾乎所有的面嚮物件語言中都有實現,概念也大同小異。UML類圖中也有同樣的概念。
類用矩形來表示,包含類名/屬性/操作,可能還有其他修飾符。
類名:根據類的屬性,可能還會有差異。比如用斜體表示抽象類;加下劃線表示靜態類。
屬性:是類的成員,用 <可見性><屬性名>: <型別> = <初始值>來表示
- <可見性>:一般+表示public;-表示private;#表示protected,也有些工具用對應的圖示來表示
- <屬性名>:為屬性取個名字
- <型別>:可以是另外一個自定義的類,也可以是基本型別;
- <初始值>:屬性的初始賦值
一般,屬性是private的可見性,為了能外部獲取和設定,分別還要寫setter和getter操作。
另外,靜態(類)屬性用下劃線表示。
操作:也是類的成員,用 <可見性><操作名>(引數名: <引數型別>):<返回值型別>來表示
- <可見性>:一般+表示public;-表示private;#表示protected,也有些工具用對應的圖示來表示
- <操作名>:為屬性取個名字
- <引數型別>/<返回值型別>:可以是另外一個自定義的類,也可以是基本型別;
一般,操作是public的可見性,為了父子類之間的重寫用protected。
另外,抽象的操作也用斜體表示;靜態(類)操作用下劃線表示。
2) 介面
介面可以認做是一種特殊的類,只包含操作不包含物件屬性。有些面嚮物件語言(比如Java)裡有這個概念,也有些語言(比如c++)根本沒有特別定義這種型別。
注:
- 接口裡也可以有介面(類)屬性的,屬於全體的,不是某一個物件的,常用來定義一些常量。
- 不同UML工具表達的介面的形狀可能也不一樣,一般的只是在類的基礎上加上《interface》的原型。
1.2 類圖中的關係
類圖中的關係有關聯(聚合、組合)、泛化、實現、依賴等。
1) 關聯(Association)
兩個類之間連線起來的關係,有方向性、多重性、可見性。
- 方向性:一個類A中訪問另一個類B的物件,是A指向了另一個類B的關聯。如果B也指向了A,那它們之間就是雙向的。
- 多重性:一個類關聯到另一個類,可能是其中多個物件的關聯,所以有1、0...*、1...*或*等多重性。
聚合(Aggregation)是整體和部分的關聯關係,用空心菱形連線整體
組合(Composition)是更強關係的關聯,不能獨立存在,即如果整體不存在部分也會消失。用實心菱形連線整體。
2)泛化(Generalization)
泛化是UML裡的概念,對應面向物件的概念裡就是繼承。用實線連線一個三角箭頭表示,子類指向父類。
3)實現(Realization)
實現用虛線連線一個三角箭頭表示,由實現類指向介面。
4)依賴(Dependency)
依賴是類圖關係中關係最疏遠的一種,應用範圍也最廣,為了描述準確,可以加上具體依賴關係的描述:access、call、import、use等。
注意:關聯關係是所有這些關係中唯一的描述類與其他類的物件之間的關係,其他關係描述的是類之間的關係。
上面簡要講述了類圖中的元素以及它們之間的關係。筆者很慶幸理論學習到的基礎在畢業之初就在做嵌入式工作中實際應用到了UML,雖然系統不是面向物件的語言來實現,但處處體現的是面向物件的思想和以及如何來表達和呈現。從事嵌入式或移動端工作的大眾用UML應該是Android興起面向物件真正實用之後。回過頭來看,實際使用16年之久了也從沒丟棄過,這裡總結一下實際應用時的最佳實踐,與諸君探討。
二、最佳實踐
1. 以交流以消除二義性為目的
UML從字面理解它還是種語言,只是這是用來建模的,所以,在你的團隊中如果有理解不一致的地方,達成一致最重要。也因了它被OMG納為了標準,更能消除方言,消除表達的二義性。
比如:
- 可見性用圖示還是符號表示;
- 介面怎麼表示;
- 類之間的關聯關係用什麼來表達:不同階段(分析/設計/實現)精化到不同層次,個人覺得能到聚合和組合關係的,別停留在關聯關係上。
而不同系統不同團隊之間,如果不是與標準向違背的前提下別試圖非要統一化別人。說這“不與標準向違背”的意思是,也有多少人真的是不求甚解,還大庭廣眾,大言不慚連基本概念都沒有的整天把順序圖說成流程圖。
2. 呈現的內容層次要一致、篇幅要恰當
類圖上呈現的當然應該是第一部分講述的內容,當然為了說明也可以有註釋等內容。這裡要說的一張類圖要呈現哪些內容:多少類/介面;多少方法/屬性。
呈現多少,這裡有些基本的前提:
- 把要描述的內容講述清楚:比如想要呈現整體架構圖,那就著重描述各種關鍵類,以及它們之間的關聯,而類具體的屬性和操作以及內部實現的內容就不要呈現了。而如果要描述一個類的實現,那另一張圖就要呈現這個類的屬性/操作以及內部的實現細節了。
- 一張圖上表達的層次要一致:不能一個類表達的外部功能,而另一個表達的很細節,是內部的實現細節,而這張圖會重點不突出,反而不如拆開表達。
- 最好是一張A4紙可以列印的下的內容:這樣清晰明瞭,讀者也容易抓住全圖。過多的表達可以拆分到另外的圖,“分而治之”。
3. 圖在開發的不同階段要呈現不同內容
在系統開發過程中,不同階段呈現的內容,讀者所關心的內容都不相同。這裡比如關聯關係,在需求階段簡單標註關聯就好,不用關注方向性、多重性等;但到了設計階段,卻是要必須明確的內容了。
4. 與其他圖的關係:靜態檢視vs動態檢視
UML圖中的各種圖都不是孤立存在的,它們之間都有關聯,把這麼圖綜合起來,才描述了系統的全貌。
類圖是靜態檢視,類的例項化是物件,某一時刻的快照(snapshot)也就是物件圖,複雜系統的關鍵場景,物件圖也很關鍵,幫助建立系統模型的全景。
而類圖中的類的例項(也就是物件)組合在一起按照時間順序的執行過程也就是順序圖。順序圖描述了物件之間按時間互動完成一個個場景,不同的場景可能需要用不同的順序圖來表達,一般的需要包含:典型場景、異常場景、邊界處理場景等。
5. UML工具
工欲善其事,必先利其器。用UML來表達,當然需要用一套專業的工具。
這裡也沒什麼特別推薦,公司已經有采購,當然Rose了。
不推薦vision,雖然vision裡也號稱可以畫UML圖,那體驗完全不是UML,跟你用畫圖板差不多。除非公司有強制要求,或獲取不到別的工具。
另外,還有些免費的或者有免費體驗版的也很不錯,說到底你用的只是體現UML概念的基本功能,沒基本功能也不能號稱支援UML x.y了。這些有starUML、VisualParadigm社群版等。