# UML類別圖的六種關係 last update : 2024/12/16 類別圖主要考慮類別的設計,所有權主要考慮對資源的生命週期的管理 1. 這六種關係是UML標準定義的 2. 這六種關係有兩種是對class定義的,有四種是對物件定義的 參考資料:[Class diagram - Wikipedia](https://en.wikipedia.org/wiki/Class_diagram#Relationships) 中文的wiki在亂寫,別看。 [(2) Albert Ma - YouTube](https://www.youtube.com/@shangpinma/search?query=%E7%89%A9%E4%BB%B6%E5%B0%8E%E5%90%91%E8%A8%AD%E8%A8%88) [Week 11-3. UML類別圖/鄭士康 - YouTube](https://www.youtube.com/watch?v=XgSx5qh4n9U&ab_channel=%E8%87%BA%E7%81%A3%E9%80%9A%E8%AD%98%E7%B6%B2GeneralEducationTW-%E9%96%8B%E6%94%BE%E5%BC%8F%E8%AA%B2%E7%A8%8BGET) UML也有定義物件圖:[[UML]學習筆記-物件圖型(Object Diagrams)-5](https://terryjryeh.blogspot.com/2019/03/uml-object-diagrams-5.html) ## 不同類別間,物件關係區分: 1. 有無他的資料成員 : 無:依賴關係;有:看2. 2. 有無has-a關係 : 無:關聯關係;有:看3. 3. 有無掌管他的生命週期 : 無:聚合;有:組合 ## dependency 這兩個教學對於依賴關係的解釋相同。 [我所理解的OOP——UML六种关系-阿里云开发者社区](https://developer.aliyun.com/article/377787) [帶你掌握 UML 類別圖的 6 種關係 | Warren Lo的沙龍](https://vocus.cc/article/65707f96fd89780001f3494b) 是一種"使用"的關係而不是擁有 = 一個類的(方法的)實現需要另一個類(的具體物件)的協助。一個類A的(一個或一些)方法的實做需要有其他類B的物件作為該方法的參數、區域變數或返回值(使用關係)。而類A本身並不需要有類B的資料成員(has-a)。 代表類A的那些會用到類B物件的方法的行為會受到當前類B物件的狀態而改變。因為類A並不知道當下類B物件的狀態(資料成員的值)。 因此依賴關係是有方向性的。最好不要設計成雙向的依賴關係。 用完就收的特性:當類A的方法執行完後,那個被用到的類B的物件並不會被保留在類A內。其實就是類A不會有類B物件的資料成員。 依賴是比較弱的關聯關係。從用法就可略知一二。關聯關係代表類A擁有類B物件資料成員(可以是引用),代表可以在該類的所有方法都用到類B物件的屬性和方法。而依賴關係是部分方法用到類B物件。 依賴是臨時性的關係 = 某些方法臨時用到某些累的物件 ## association 大概是說一個類A的物件"知道/知曉"類B的物件,但並沒有"has-a"的關係。 這裡的知道/知曉是類A有類B物件的引用。關聯也有單向跟雙向的。 組合以及聚合是比較強的association,不只有"知曉"的關係,還是"has-a"的關係。 ## 組合 聚合 考慮"物件"之間"has-a"的關係,可分為組合以及聚合。 懶人包 : 組合:掌管(成分類別物件的)生命週期,負責成分類別物件(宣告為實體物件成員)的創建及銷毀。 聚合:不掌管(成分類別物件的)生命週期,不負責成分類別物件(宣告為指標成員)的創建及銷毀。 ## UML圖畫法: 看大話設計模式第一章 or [簡單理解 UML 類別圖 - Sunny Cheng - Medium](https://misomiso43.medium.com/%E7%B0%A1%E5%96%AE%E7%90%86%E8%A7%A3-uml-%E9%A1%9E%E5%88%A5%E5%9C%96-f0b32a3272c) A has-a B : aggregation : A◆→B composition : A◇→B ## 用於描述物件/對象間的關係 1. aggregation : objA owns objB = 弱的包含("has-a")關係。: 但是A跟B各自有各自的生命週期。e.g.如果該物件成員可被多個物件共享 = 它有自己的生命週期 = 是聚合關係 有人稱Aggregator (Whole) 跟 Aggregatee (Part) 2. composition : objB is a part of objA = 強的包含("has-a")關係 : A掌管B的生命週期 ### 如何判斷物件間的關係是組合還是聚合 看主體類別有無掌管成分類別的生命週期。取決於寫程式的人的生活經驗以及需求。因為很有可能根據需求的不同,物件間可以是組合也可以是聚合關係。比如車子引擎輪胎之間的關係:[Polymorphism題目 vehicle engine tires - HackMD](https://hackmd.io/@S-gwYZv8RkKi_mnmtTIOCw/ryZlyMXXye) ### 實做注意事項 #### 聚合 1. 成分類別必須是指標或引用(通常是用指標,好用且可用於polymorphism)。因為如果是實例的話,它的生命週期就被掌管 = 主體被銷毀,成分類別也被銷毀。 2. objA owns objB。B需要在外部建立,再傳給A。最好不要由A去建立B,但卻不負責銷毀它,很容易記憶體洩漏。想想你在trace別人的code,在main()中建立一個objA然後他被銷毀。我們完全不知道記憶體還有個objB要我們去銷毀。 3. 誰建立該物件誰就要負責銷毀它。比如在main()建立的物件就要在main銷毀它。A建立的物件A就要負責銷毀它(組合) #### 組合 1. 成分類別通常是實體物件,也可以是指標(通常是為了實現多型),或是指標引用。但作為指標的話,new該物件成員最好用在主體物件的建構子的引數,不要宣告在外面(比如main),這樣看code的人才不會被混淆(為何在外面new了卻沒被delete),並且主體物件需要負責銷毀它。(補充:不會是引用,因為不能用引用去銷毀該物件,除非是指標引用) 成分類別用指標的例子:[State in C++ / Design Patterns](https://refactoring.guru/design-patterns/state/cpp/example?_gl=1*1chx3pv*_ga*MTM5NjM0OTAzMi4xNzI5MDQ5NDcy*_ga_SR8Y3GYQYC*MTczMjg2MDM1NS44OC4wLjE3MzI4NjAzNTUuNjAuMC4w) ```cpp= //這樣寫不好,沒人知道MyClass會delete mem_obj int main() { MemberClass mem_obj = new MemberClass; MyClass obj = new MyClass(mem_obj); } ``` ```cpp= //這樣寫比較好一點,看code的人會認為MyClass要負責銷毀該MemberClass物件 int main() { MyClass obj = new MyClass(new MemberClass); } ``` 2. A掌管B的生命週期意思是A負責B的建立以及銷毀。要注意當A被銷毀(主動銷毀、被被動銷毀、非預期銷毀)時,要確保B有被銷毀。 #### 補充:銷毀種類 一個物件被銷毀的幾種情況(我想得到的): 1. 主動銷毀:(情況:他是動態配置)delete它 2. 被動銷毀:靜態配置(out of scope) 3. 非預期銷毀:exception occurr(我不太了解)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up