Files
Obsidian-Main/-20.01. Programming/UML.md

5.1 KiB
Raw Blame History

玩轉設計模式 - 看懂UML類圖

前言

作為設計模式系列的第一篇我準備先分享下如何看懂UML類圖看完這篇文章你就能看懂類圖中各個類之間的關係以及線條、箭頭都代表什麼意思。 同時,我們會將類圖所表達的含義和最終的代碼實現對應起來; 有了這些知識,看後面章節的設計模式結構圖就沒有什麼問題了。

先看一個例子

下面是我畫的一張類圖使用的工具是StarUMLMac版本下載地址

  • 數碼是斜體的,表示數碼是一個抽象類
  • 數碼有兩個繼承類,分別是手機和電腦,他們之間的關係是實現關係,用帶空心箭頭的虛線表示
  • iPhone與手機之間也是繼承關係他們之間的關係是泛化關係,用帶空心箭頭的實線表示
  • 手機由屏幕和主板等組合而成,他們之間的關係是組合關係,用帶實心菱形的實線表示
  • 程序員上班必須要用電腦,他們之間的關係是依賴關係,用帶箭頭的虛線表示
  • 程序員與公司之間是聚合關係,用帶空心菱形的實線表示
  • 程序員一般都會有自己的工牌,他們之間的關係是關聯關係,用實線表示

以上例子和圖中我都把類的六種關係特別標註出來了,下面我們具體講講這六種關係

類之間的關係

類的繼承結構表現在UML中為實現泛化

繼承關係為 is-a的關係兩個對象之間如果可以用 is-a 來表示,就是繼承關係

實現Realization

“數碼”是一個抽象概念在現實中並不能直接用來定義對象必須指明它的子類比如手機和電腦。“數碼”這個類在java中可以用接口或者抽象類表示在C++中用抽象類表示。

代碼實現:實現關係表現為繼承抽象類。

泛化Generalization

手機在現實中有實現可以用來定義具體的對象iphone是手機的子類手機和iphone的關係為泛化關係。

代碼實現:泛化關係表現為繼承非抽象類。

聚合Aggregation

聚合表示兩個對象之間是整體和部分的弱關係,生命週期不同步,部分的生命週期可以超越整體,比如程序員和公司,公司倒閉了,但程序員還在,還可以去其他公司。

代碼實現:聚合關係以成員變量的形式實現,只是成員變量的賦值時機是在類方法裡,代碼如下:

//第一種是在set方法裡直接設置子類的實例
class Company {
    private Programmer programmer;

    public void setProgrammer(JavaProgrammer javaProgrammer) {
        programmer = javaProgrammer;
    }
}

//第二種方式是在set方法裡直接寫死直接定義一個初始值
class Company {
    private Programmer programmer;

    public void setProgrammer() {
         programmer = new JavaProgrammer();
    }
}
複製代碼

組合Composition

組合表示兩個對象之間是整體和部分的強關係,生命週期一致,部分的生命週期不能超越整體,或者說組合中的整體不能缺少部分。就像手機不能缺少屏幕和主板一樣。

代碼實現:組合關係以成員變量的形式實現,只是成員變量的賦值時機是在類構造方法裡,代碼如下:

//手機由屏幕組成
class Phone {
    private Screen screen;

  	//創建手機的時候同時創建屏幕
    public Phone() {
        screen = new Screen();
    }
}
複製代碼

關聯Association

關聯表示的是兩個不同對象之間存在的固定的對應關係,它是一種靜態關係,和運行狀態無關

代碼實現:關聯關係也是以成員變量的形式實現,只是成員變量的賦值時機是在聲明這個變量的時候,代碼如下:

//程序員都會有工牌
class Programmer {
    private Card card = new Card();
}
複製代碼

依賴Dependency

依賴表示的是一個對象在運行期間會用到另一個對象的關係,與關聯關係不同的是,它是一種臨時性的關係,通常在運行期間產生,並且隨著運行時的變化,依賴關係也可能發生變化。比如程序員在工作的時候會用到電腦,程序員是依賴電腦的。

代碼實現:依賴關係主要可以通過方法參數、方法局部變量、靜態方法三種方式實現,方法參數代碼如下:

class Programmer {
  	//程序員工作的時候需要用到電腦
    public void work(Computer computer) {
        computer.work();
    }
}
複製代碼

總結