# Unified Modeling Language There are lots of type diagrams of the UML. One of the diagrams is Class Diagram. ## Class Diagram ![](https://i.imgur.com/LCeVNyz.png) Class Diagram 表示法,一個長方形,切格成三個部分,分別為 * Class name * 一般類別 用**粗體** 表示 * 抽象類別 用*斜體* 表示 * Attributes * Methods * 存取資格 * "+" public * "-" private * "#" protected * "~" package ## Relationship 各個Class之間會存在不同關係,關係由強到弱的排列。 * Composition 組成 (網頁與Header/body的關係) * 我存在,你存在; 我死,你也死了。 * Aggregation 聚合(球隊與球員的關係) * * Assotiation 關聯(醫生與病人關係),兩種Class 可以單獨存在。 * Dependecy 依賴(圖書館與圖書的關係),某個Class改變,相對會影響到另一個Class。 * Inheritance 繼承 * Implementation 實作 ### Composition(Class 之間)為組成關係 > Composition relationships when objects are composed of(or made up of) other objects. 上面意思是,對象由其他對象組成。 > Objects in a composition relationship cannot, conceptually, exist in isolation. 類別屬於這種關係的,概念上這種關係的兩種類別是不能單獨存在的。 另一種說法由生命週期來說 > 部份物件和整體物件的生命週期是一樣的。 網頁與Header/body的關係,就是這樣。 ![](https://i.imgur.com/l2LcwVQ.png) ### Aggregation (Class 之間) 為聚合關係 文字定義: > the formation of a number of things into a cluster. UML其中一種解釋如下: > Aggregation relationships exist when classes aggregate variables of other classes type. > 另一種說法: > A物件可以包含B物件,但B物件不是A物件的一部分 ~~我的想法則是某個 Class 擁有 owns a 另一個的陣列~~ 舉球隊與球員例子說明 ![](https://i.imgur.com/mYZoAmo.png) 從球隊來看:一個球隊可以有零到多個球員(0..*)。 從球員來看: 一個球員只可以屬於其中一個球隊,但不一定要屬於任一球隊。 程式實作如下 ``` public class Team { private String name; private String slogan; private String city; private List<Player> players = new ArrayList<>(); public void addPlayer(Player player){ this.playes.add(player); player.setTeam(this); } public void removePlayer(Player player){ this.players.remove(player); player.setTeam(null); } } ``` ``` public class player { private String name; private Int age; private String homeTown; private Team team; } ``` ### Assotiation(Class 之間)為關聯(瓜葛)關係 > Assotiation relationships often exist when classes have variables of other types, that they can invoke operations on. 當某些類別具有其他類別的變數,而且他們(某些類別)可以在其上(其他類別的變數)調用操作。 > 類別 "知道" 另一種類別 聚合與關聯的差別是我自己在研究的時候會搞不清,以下為我可以接受的解釋。 > 但是關聯關係所涉及的兩個類是處在同一層次上的,而在聚合關係中,兩個類是處在不平等層次上的,一個代表整體,另一個代表部分。 https://www.itread01.com/content/1547933415.html **Aggregation -> 不同層級** **Associtation -> 相同層級** 以病人與醫生的類別關係舉列 ![](https://i.imgur.com/NCs5CnM.png) 醫生與病人的關係,在架構上並沒有層級之分,所以是關聯的關係而不是聚合關係。 另外此處數字判讀為,一個醫生可以有零到多個病人。而從病人端判讀為,一個病人只能接受一個醫生進行治療。 ### Dependency(Class 之間)為依賴關係 > Dependency relationships exist when classes depend on each other in such a way that a change to one class may affect the other, such as when one class accepts an instance of another class as parameter to a method. 當某個類別改變時,會影響到另一個使用到它的類別。當有某個類別的方法把另個類別的實際物件當作參數時。 舉圖書館與書的例子。 ![](https://i.imgur.com/m55fx5u.png) 圖書館類別有一個方法會傳回一個書的類別。而改變書這個類別,相對會影響到圖書館這個類別。 Since the Library class has a method that returns a Book, changes to the Book class could result in changes to the Library class (based on how Book objects are created). ### Inheritance (Classs 之間) 為繼承關係 > It indicates that one of the two related classes (the subclass) is considered to be a specialized form of the other (the super type) and the superclass is considered a Generalization of the subclass. 父類別的架構比子類別的架構來得更廣泛,舉建築物來說,建築物最基本會有屋齡和地址,但有著不同的建築物,例如說因為在21世紀電動車較廣泛,因此現在的建築物會有充電樁這個attribute,但同時還是保有屋齡和地址的特徵。 ![](https://i.imgur.com/do669Mr.png) ### Implementation (Class 之間) 為實作關係 > 實作interface的所規範的方法。 以交易的例子來說,**ApplePay**這個實例需要實作付款這個規範,同樣的**信用卡**付款也需要實作付款這個界面規範。 ![](https://i.imgur.com/ZEGBuKV.png) ## 畫出Class Diagram 表達以下設計 ### 一個縣市類別,有多個行政區類別 #### 假設分析 假設每個縣市類別至少有一個行政區,每個行政區都屬於一個縣市。縣市和行政區似乎不能單獨,獨立存在。所以是組合Composition關係。 ![](https://i.imgur.com/sjT3R3P.png) ### 每個縣市類別只有一個市長類別,且市長只能任職於單一縣市 #### 假設分析 一開始會認為縣市與市長是聚合Aggregation的關係。很像球隊與球員的關係。但細想如果一個縣市不存在,首長也不會存在了。所以是組合關係。 ![](https://i.imgur.com/nZ0JWR3.png) ### 行政區中存在多個生活圈,且生活圈可隸屬於複數個行政區 #### 假設分析 行政區與生活圈應該是有層級上的不一樣,生活圈在行政區之下。假設行政區可以擁有零到多個生活圈。生活圈至少屬於一個行政區。 ![](https://i.imgur.com/1umBxd8.png) ### 市長類別具備三個屬性: 姓名(字串)、上任日期(日期)、個人代碼(數字),前兩個屬性為public,第三個屬性為private。 ![](https://i.imgur.com/wHoaRBY.png) ### 市長具備兩種可執行的行為: 連任,輸入日期無回傳; 領薪水,無輸入、回傳整數。 ![](https://i.imgur.com/ZPthjNu.png) ## 請設計並畫出Class Diagram 回應以下需求 ### 透過API取得在當前地圖範圍內的生活圈,同時顯示在地圖與列表上 #### 分析 假設就字面上意思,不多加其他類別,例如: 生活圈Page。 就Vue.js 改變attributes,可以讓頁面重新render。 ![](https://i.imgur.com/xj4RjDS.png) #### 優化 假設多一個物件,生活圈Page,這是一個Container,裡面有一個地圖類別實例(instance)和一個列表實例(instance)。這樣可以把生活圈Array拉高到生活圈Page。 ![](https://i.imgur.com/yRUHY5z.png) #### 加入vuex後的優化 ![](https://i.imgur.com/AxDIqhj.png) ### 地圖可以拖曳、縮放 #### 分析 ![](https://i.imgur.com/nPhNnkk.png) ### 地圖被拖曳、縮放時,會重新呼叫API取得範圍內的生活圈 #### 分析 地圖拖曳、縮放,會改變地圖的中心點和地圖的半徑,這兩個Attributes(state),設計是只要states 一改變,就會呼叫API ![](https://i.imgur.com/Ln0kS5D.png) ### 點擊列表上的卡片時,被點選的卡片與地圖上的生活圈同步變色 #### 分析 想法是生活圈裡有一個attribute叫做isSelected,列表裡的卡片或是地圖上的區塊被點選到的時候會更新生活圈isSelected的值 ![](https://i.imgur.com/qrduqOu.png) ### 一次只有一個卡片變色 ## 請分別說明軟體設計原則SOLID,並劃出對應的Class Diagram範例 ### 單一職責原則 Single Responsibility Principle > 每個物件,不管是類別,函數,負責的功能,都應該只做一件事 > 根據這樣的描述,物件的關係應該像是Composition 組成的關係。 以網頁的Header/Body為例 ![](https://i.imgur.com/l2LcwVQ.png) ### 開放封閉原則 Open-Close Principle > 藉由增加新的程式碼來擴充系統的功能,而不是藉由修改原本已經存在的程式碼來擴充系統的功能 > 開放封閉原則可以用Class Diagram裡的繼承關係表示。不過這也代表在程式開發時,最初要設想這個物件最基本的功能。不然就是在程式開發時,做到相關物件的時候要整理歸類。這樣才能繼承後擴充功能。 以房屋為例,在沒有電動車以前,房屋這個物件是不會有充電樁。所以在開發時物件可以繼承最基本的房屋類別,再加上別的attributes ![](https://i.imgur.com/JX6FVHH.png) ### 里氏替換原則 Liskov Substitution Peinciple > 所有父類的功能都可以用其subclass來實現。 ### 接口隔離原則 Interface Segregation Principle > 針對不同需求的用戶,開放其對應需求的介面,提拱使用。可避免不相關的需求介面異動,造成被強迫一同面對異動的情況。 > 意思就是介面要盡量細分,不要讓類別在實踐介面時,產生不需要實踐的現象。 以房屋物件為例,假設一個建案實例裡,有一個直接連絡的功能和賞屋的功能,預售屋與中古屋、新成屋最大的不同是無屋可賞。所以介面上可以分開。 ![](https://i.imgur.com/UYDzQ9m.png) ### 依賴反轉原則 Dependency Inversion Principle > 當A模組在內部使用B模組的情況下,我們稱A為高階模組,B為低階模組。 > 高階模組不應該依賴於低階模組,**兩者都該依賴抽象介面**。 舉例假設樂居未來的地圖,可以選擇用GoogleMap或AppleMap或其他地圖呈現,那設計架構如下。 ![](https://i.imgur.com/z6NRJ3G.png) ## 參考資料 [1]http://glj8989332.blogspot.com/2018/02/design-pattern-uml.html [2]https://ithelp.ithome.com.tw/articles/10191553 [3]https://medium.com/@nwyyy/solid-%E4%B9%8B-s-%E5%96%AE%E4%B8%80%E8%81%B7%E8%B2%AC%E5%8E%9F%E5%89%87-305b9ad65e6f [4]https://spicyboyd.blogspot.com/2018/07/umlclass-diagram-relationships.html [結合角色]https://joeshua.pixnet.net/blog/post/36126772