設計模式存在哪些關聯關係,六種關係傻傻分不清--- UML圖示詳解

煙花散盡13141發表於2022-05-16

前言

  • UML俗稱統一建模語言。我們可以簡單理解成他是一套符號語言。不同的符號對應不同的含義。在之前設計模式章節中我們文章中用到的就是UML類圖,UML除了類圖意外還有用例圖,活動圖,時序圖。
  • 關於UML如何繪製,這裡主要推薦兩種方式一種是通過draw.io,另外一種就是Rational Rose這個軟體。processon免費版有個數限制

繪製你的第一個UML類圖

 public class Person {
     private Integer id;
     private String name;
 ​
     public String getName() {
         return name;
     }
 ​
     public void setName(String name) {
         this.name = name;
     }
 }
  • 現在我給你一個類,假如這個類很抽象別人無法理解或者別人現在不想看程式碼去理解,你如何快速讓別人看懂結構呢?UML就是這個作用。那麼對於上面Person類我們該如何繪製類圖呢
  • 這個類很簡單,一個類名,兩個屬性,兩個方法。我們只要知道UML類圖中如何表示類,如何表示屬性如何表示方法即可。

image-20220505184816035.png

  • 我們只需要如上表示即可。每個軟體顯示的風格不一樣。我們不需要在意那些細節。有的軟體屬性和方法前面不全是+號表示的。這裡自己注意下就好。總體分位三塊,第一塊表示類名,第二塊表示屬性,第三塊表示方法

image-20220505185311911.png

類之間關聯關係

  • 之前我們學習里氏替換原則的時候有提到我們繼承時子類不要改變父類的意圖。也是防止我們過度的繼承。除此之外我們還有學習介面隔離原則。
  • 關於介面隔離原則主要體現在介面與實現類上。
  • 依賴倒轉原則主要也是面向介面程式設計
  • 還記得我們在講解開閉原則的時候應為我們圖形後期的不斷擴張導致我們程式改動特別大。就是因為我們沒有處理好類與類的關係。我們的解決思路是將邏輯部分進行轉移。各司其職的去做某一件大事。需要相互配合的時候我們當時通過依賴的方式的進行功能的傳遞的。
  • 上述或多或少我們都接觸到了關聯關係。今天我們就來好好整理下類與類之間到底存在哪些關係

image-20220505192922336.png

  • 上面六種關係就是類與類之間的關係狀態。我這裡也將每種關係狀態對應的UML表示方式表現出來了。這裡申明下我用的是draw.io這個工具。表示的如有錯誤還請大家指出。
  • 下面我們每兩個為一組進行對比學習,這樣更有助於我們的理解

依賴&關聯

依賴

  • 首先最常見的類關係應該就是依賴了。我的理解依賴是類關係的一種籠統化。甚至其他物種類關係都是依賴的一種特殊情況。
  • 依賴顧名思義就是類中使用到別的類,那麼就是依賴關係
 public class DependencyAndRelation {
     private Dependency dependency;
 ​
     public void createRelation(Relation relation) {
 ​
     }
     public Study startStudy() {
         return null;
     }
     public void fav(){
         Eat eat = new Eat();
     }
 }
 class Dependency{}
 class Relation{}
 class Study{}
 class Eat{}
  • 上面程式碼DependencyAndRelation中分別通過屬性方式使用到Dependency;通過入參方式使用到Relation;通過出參方式使用到Study;通過區域性變數的方式使用到了Eat ; 上述方式都稱為依賴關係。

image-20220506082410599.png

  • 我們通過帶箭頭的虛線來表示我們的依賴關係,箭頭所指被依賴類。通過UML圖我們將上述DependencyAndRelation進行繪製。

image-20220506191619560.png

關聯

  • 你可能在好奇關聯不就是依賴嗎。其實我也覺得關聯就是依賴。產生關聯一定是依賴。存在依賴也一定是關聯。這句話沒毛病。
  • 但是設計模式大佬們非要較真,那我們也只能按照大佬的意思來理解了。
  • 非要說出個區別來,那就只能指出他們兩者的方向性了。依賴在UML種是帶箭頭的虛線。而關聯是一條實線,這應該就是他們之間的區別了。
  • 上面我們也通過案列來說明判定是依賴的三種情況。只要使用過不管是不是永久的都叫做依賴。俗稱一日為師終生為師。

image-20220506192636923.png

  • 準確的說關聯是存在三種關聯關係的,一種是沒有方向屬於從屬關係(實際也是單向關聯),雙向關聯和單向關聯。
  • 單向關聯就是A種有B,B種無A;
  • 雙向關聯是AB中互相依賴對方。
  • 到這裡你也會發現,這個關聯實際上就是依賴關係呀。對!沒錯,實際就是對依賴的細化。還是上面的程式碼我們照樣可以將虛線箭頭

image-20220506193259851.png

泛化&實現

  • 泛化就是對應Java中的抽象;實現對應的Java中的介面。他們兩個在UML中都是有三角形箭頭指明方向的。
 public class ExtendAndImplent {
 }
 abstract class Happy{
     abstract void sayHi();
 }
 ​
 class TodayHappy extends Happy {
 ​
     @Override
     void sayHi() {
         System.out.println("我今天很開心");
     }
 }
 ​
 interface Operator{
     public void opt();
 }
 ​
 class AddOperator implements Operator {
 ​
     @Override
     public void opt() {
         System.out.println("我會加法");
     }
 }
  • 上面程式碼很簡單就是演示了一下抽象和介面的定義以及各自的子類實現。對應UML類圖

image-20220506195336362.png

聚合&組合

  • 剩下就是聚合和組合了。其實真的不是很理解為什麼要搞出這麼多的名詞,徒增煩惱罷了!
  • 聚合更像是一個集體,集體可以解散,解散後個體仍然存在;而組合更像是組裝,組裝解散後個體的零散零件將會失去整體的意義
  • 比如一個國家有很多人組成,假如國家倒閉了,人還是一樣的存在,這就叫聚合;
  • 比如一個貓是由頭,爪子,尾巴組成,這些在一起是一隻貓,這就叫組合,這裡面任何一個脫離了貓都將是殘缺的。

image-20220507084435379.png

聚合

 public class AggregationAndComposition {
     public static void main(String[] args) {
         Cat cat = new Cat();
     }
 }
 class Cat{
     private Appendage appendage;
 }
 class Appendage{
 ​
 }
  • 上面這段程式碼展示的就是聚合的關係。因為對於Cat類來說Appendage並不是必須的。是否是必須的從程式的角度看唯一標準就是是否Appendage隨著Cat類一起生成。很顯然我們建立了Cat類之後Appendage並沒有被建立。

image-20220507084806942.png

  • 聚合是一條帶箭頭的實現,但是僅僅是帶箭頭的實線已經表示了單向關聯關係了。所以在箭頭的另外一側我們又新增了一個菱形。菱形側表示聚合的集合。上圖中表示Context中包含(依賴)State這個類。包含可能是1個也可能是多個。在菱形側我們可以通過數字來表示一個還是多個

組合

 public class AggregationAndComposition {
     public static void main(String[] args) {
         Cat cat = new Cat();
     }
 }
 class Cat{
     private Appendage appendage = new Appendage();
 }
 class Appendage{
 ​
 }
  • 在程式碼層面上只需要將程式碼稍作修改,聚合的關係就變成了組合。理論上我們知道組合是不可分割的。在程式碼中翻譯過來就是依賴的類一起被建立。
  • 組合和聚合UML也很好區分。聚合是空心菱形,組合是實心菱形。

image-20220507085937563.png

小結

  • 這裡需要注意下,圖中也指出了聚合和組合的箭頭並不是必須的。有沒有箭頭都是表示聚合或者組合。看個人喜好吧。我個人比較帶上箭頭比較有方向感。
  • 如果像上面關聯一樣如果雙向聚合呢?理論上是不會出現也不應該出現這種情況的。但是保不齊就有人這麼搞。如果真的這樣我猜測兩端都用對應的菱形表示即可。這時候就沒有箭頭一說了。

\

相關文章