返回文章列表

UML 基礎與使用案例模型解析

本文介紹統一建模語言(UML)的基礎知識,重點闡述使用案例模型的建立、元素、關係以及敘述的撰寫方法。同時,文章也探討了UML的演進、複雜性、學習曲線以及在軟體設計中的重要性。此外,還提供程式碼範例,示範如何將UML使用案例應用於實際的軟體開發過程中,並解析程式碼的關鍵部分,幫助讀者更好地理解UML的實際應用。

軟體工程 系統設計

UML 作為一種標準化的視覺化建模語言,廣泛應用於軟體開發和系統設計領域。它能有效地捕捉系統需求、促進團隊溝通並提升軟體品質。理解 UML 的基本概念和應用技巧對於軟體工程師至關重要。本文將探討 UML 的核心元素、使用案例模型的建立與應用,並結合程式碼範例進行實務解析,協助讀者掌握 UML 的精髓。從使用案例圖的基本元素(參與者、使用案例、系統邊界)到使用案例之間的關係(包含、泛化、擴充套件),文章將逐步引導讀者理解如何使用 UML 建立清晰的系統模型。此外,文章也涵蓋了使用案例敘述的撰寫技巧,包括事件流程、替代流程以及如何處理多重路徑,並提供表格範例,讓讀者更易於理解和應用。

統一建模語言(UML)基礎介紹

統一建模語言(UML)是一種用於軟體設計的圖形化開發語言,用於描述軟體系統的需求和規範。最新的IEEE軟體設計檔案(SDD)標準便是根據UML的概念構建,因此我們將先介紹UML的背景和特性,然後探討如何利用UML實作使用案例,以清晰、一致地呈現軟體系統設計。

UML 標準的演進

UML起源於1990年代中期,由三種獨立的建模語言合併而成:Booch方法(Grady Booch)、物件建模技術(Jim Rumbaugh)和物件導向軟體工程系統(Ivar Jacobson)。在這初始整合之後,物件管理組織(OMG)在1997年開發了第一個UML標準,並持續由OMG管理至今。由於UML本質上是透過統一多種方法而設計的,它包含了許多不同的方式來描述同一件事,導致系統記憶體在大量的冗餘和不一致性。

為何使用 UML?

儘管UML存在一些缺點,但它仍然是一種相當完整的物件導向設計建模語言。同時,它已成為IEEE事實上的檔案標準。因此,即使您不打算在自己的專案中使用UML,您仍需要能夠讀懂它,以便處理其他專案的檔案。由於UML已經廣泛流行,您的專案利益相關者很可能已經熟悉它。就如同C程式語言(或BASIC,如果您不熟悉C):儘管它的語言設計不佳,但每個人都知道它。

UML 的複雜性與學習曲線

UML是一種非常複雜的語言,需要大量的學習才能掌握,這超出了本文的範圍。幸運的是,市面上有許多優秀的UML相關書籍,其中一些甚至長達近1000頁(例如Tom Pender的《The UML Bible》;參見第88頁的「更多資訊」)。本章及後續章節的目的並不是讓您成為UML專家,而是快速介紹本文其餘部分會用到的UML功能和概念。這樣,當您在後續章節中遇到UML圖表時,可以參考這些章節以便更好地理解。

UML 使用案例模型

UML使用使用案例來描述系統的功能。使用案例大致對應於一個需求。設計師建立使用案例圖來描述系統從外部觀察者的角度看起來做了什麼,這意味著他們只描述系統做了什麼,而不描述它如何做。然後,他們會建立使用案例敘述來填補圖表的細節。

使用案例圖的元素

使用案例圖通常包含三個元素:參與者、通訊連結(或關聯)和實際的使用案例:

  • 參與者,通常以簡筆人物圖表示,代表使用系統的使用者或外部裝置和系統。
  • 通訊連結以一條線表示,連線參與者和使用案例,表明兩者之間存在某種形式的通訊。
  • 使用案例以橢圓形表示,包含適當的描述,代表參與者在系統上執行的活動。

圖4-1展示了一個使用案例圖的範例。

圖示解說:

此圖示展示了一個簡單的使用案例圖,其中包含兩個參與者和一個使用案例。參與者透過通訊連結與使用案例相連,表示他們與系統進行互動。

UML 與使用案例簡介

UML(統一建模語言)是一種用於軟體開發的標準化建模語言,其中使用案例圖(Use Case Diagram)是描述系統功能需求的重要工具。使用案例圖透過圖形化的方式展示了系統的使用者(角色)與系統之間的互動關係。

使用案例圖的基本元素

使用案例圖主要包含三個基本元素:角色(Actor)、使用案例(Use Case)和系統邊界。

角色(Actor)

角色代表了與系統互動的外部實體,可以是人、其他系統或硬體裝置。在UML中,角色通常用一個簡筆人物圖示表示,但也可以使用帶有«Actor»標記的矩形來表示,以節省空間和減少混亂。

使用案例(Use Case)

使用案例描述了系統為角色提供的某項功能或服務。每個使用案例都應該有一個簡潔且獨特的名稱,以清晰地描述其功能。例如,“選擇脈衝操作”或“生成個別兆瓦時報告”等。使用案例在圖中以橢圓形表示。

使用案例圖的建立

建立使用案例圖時,需要識別出系統中的角色和使用案例,並描述它們之間的互動關係。以下是一些關鍵步驟:

  1. 識別角色:確定與系統互動的外部實體。
  2. 識別使用案例:描述系統為角色提供的功能或服務。
  3. 繪製使用案例圖:使用UML符號繪製圖形,展示角色和使用案例之間的關係。

使用案例的包含關係

當多個使用案例具有共同的功能或步驟時,可以使用包含關係(Inclusion)來避免重複描述。包含關係透過在包含的使用案例和使用被包含的使用案例之間繪製一條帶有«include»標記的虛線箭頭來表示。

圖示說明

此圖示展示了一個使用案例包含另一個使用案例的關係,箭頭指向被包含的使用案例。

使用案例的泛化關係

當多個使用案例分享某些共同的行為或特性時,可以使用泛化關係(Generalization)來描述這種繼承關係。泛化關係透過在特定的使用案例和更一般的使用案例之間繪製一條帶有空心箭頭的實線來表示。

圖示說明

此圖示展示了特定的使用案例如何繼承一般使用案例的行為。

實際應用範例

考慮一個核反應堆積控制系統,該系統有多個操作員角色,包括反應堆積操作員和高階反應堆積操作員。該系統提供了多個使用案例,例如“選擇百分比功率”和“生成報告”等。透過使用UML使用案例圖,可以清晰地描述這些角色與系統之間的互動關係,以及不同使用案例之間的包含和泛化關係。

圖示說明

此圖示展示了不同操作員角色如何與系統互動,以及不同使用案例之間的泛化和包含關係。

UML 與使用案例簡介

4.2.4 使用案例的繼承

在 UML 中,使用案例的繼承(generalization)允許一個使用案例繼承另一個使用案例的特性和活動。繼承關係透過一條帶有空心箭頭的實線表示,箭頭指向被繼承的使用案例,而箭尾連線到繼承的使用案例。在圖 4-9 中,「產生報告」(Generate reports)是基礎使用案例,而「個別 MWH 報告」(Individual MWH report)和「所有報告」(All reports)是衍生使用案例。

內容解密:

此圖示展示了使用案例之間的繼承關係。其中,「產生報告」是基礎使用案例,而「個別 MWH 報告」和「所有報告」則繼承了「產生報告」的特性和活動,並在此基礎上增加了各自特有的功能。

衍生使用案例繼承了基礎使用案例的所有特性和活動。也就是說,基礎使用案例中的所有專案和功能在衍生使用案例中都存在,同時衍生使用案例還具有一些獨特的專案。在圖 4-9 中,Reactor Operator 角色只能選擇「個別 MWH 報告」,因此,由 Reactor Operator 角色生成的任何報告都遵循與該個別報告相關的步驟。而 Sr. Reactor Operator 角色則可以生成從「所有報告」或「個別 MWH 報告」使用案例衍生的任何報告。

儘管繼承看起來與包含(inclusion)非常相似,但兩者之間存在細微差別。包含是指一個使用案例完全被另一個使用案例包含,而繼承則是基礎使用案例透過衍生使用案例得到增強。

4.2.5 使用案例的擴充套件

UML 中的使用案例擴充套件允許指定某些使用案例的可選(條件)包含。繪製擴充套件關係時,使用「extend」而非「include」,並且箭頭是一條帶有實心箭頭的虛線。另一個不同之處在於,箭頭指向被擴充套件的使用案例,而箭尾指向擴充套件的使用案例,如圖 4-10 所示。

內容解密:

此圖示展示了使用案例之間的擴充套件關係。其中,「擴充套件使用案例1」和「擴充套件使用案例2」透過擴充套件關係與「被擴充套件使用案例」相連,表示它們為「被擴充套件使用案例」提供了可選的功能或條件處理。

使用案例擴充套件在需要根據內部系統或軟體狀態選擇不同的使用案例時非常有用。一個典型的例子是錯誤或例外處理條件。假設有一個小型的命令列處理器,可以識別某些以動詞開頭的命令(如 read_digital)。命令語法可能如下:

read_digital port#

其中 port# 是一個表示要讀取的埠的數字字串。當軟體處理這個命令時,可能會出現兩種錯誤:port# 可能存在語法錯誤(即它不代表一個有效的數字值),或者 port# 的值超出範圍。因此,處理這個命令可能有三種結果:命令正確並讀取指定的埠;發生語法錯誤,系統顯示適當的錯誤訊息;或者發生範圍錯誤,系統顯示適當的錯誤訊息。使用案例擴充套件可以輕鬆處理這些情況,如圖 4-11 所示。

內容解密:

此圖示展示了一個具體的使用案例擴充套件範例。「讀取埠命令」是主要的使用案例,而「語法錯誤」和「範圍錯誤」則是透過擴充套件關係與之相連的可選處理條件。

4.2.6 使用案例敘述

單純的使用案例圖並不能解釋任何細節。實際的使用案例(相對於使用案例圖)是文字而非圖形。圖形提供了一個「執行概要」,使外部觀察者能夠區分不同的活動,但真正描述使用案例的是使用案例敘述。儘管沒有明確規定使用案例敘述中應包含的專案,但它通常包含表 4-1 中列出的資訊。

表 4-1:使用案例敘述專案

使用案例敘述專案描述
相關需求與使用案例相關的需求標籤或其他指示,提供對 SyRS 和 SRS 檔案的可追溯性。
角色與使用案例互動的角色列表。
目標/目的/簡要描述對目標及其在系統內的上下文的描述,以闡明使用案例的目的。
假設和前置條件對執行使用案例之前必須為真的條件的描述。
觸發器啟動使用案例執行的外部事件。
互動/事件流程外部角色在執行使用案例期間與系統互動的逐步描述。
可選互動/替代事件流程與互動步驟描述不同的替代互動。
終止條件結束使用案例的條件。
結束條件描述使用案例成功終止或失敗時的情況。
後置條件在完成使用案例執行後(成功或失敗)適用的條件。

額外的專案可能包括:

  • 最小保證
  • 成功保證
  • 對話(有效地與互動另一個名稱)
  • 次要角色
  • 擴充套件(可選/條件互動的另一個名稱)
  • 例外(即錯誤處理條件)
  • 相關使用案例(即其他相關的使用案例)
  • 利害關係人(對使用案例感興趣的人)
  • 優先順序(在實作中使用案例之間的優先順序)

4.2.6.1 使用案例敘述的形式化程度

使用案例敘述的形式化程度可以從隨意到完全正式。隨意的使用案例敘述是一種自然語言(如英語)的描述,沒有太多的結構。隨意的敘述適合小型專案,並且常常因使用案例而異。

完全正式的使用案例敘述是一種正式的描述,通常透過表單建立,定義了專案的所有敘述專案。完全正式的使用案例敘述可能由三個部分組成:

  • 使用案例專案的列表,不包括對話/事件流程/互動和替代事件流程/可選互動專案。
  • 主要事件流程。
  • 替代事件流程(擴充套件)。

此圖示說明瞭不同形式的使用案例敘述及其組成部分。

內容解密:

此圖示展示了不同形式的使用案例敘述,包括隨意和完全正式的形式。它們各自具有不同的特點和組成部分,以滿足不同專案的需求和複雜度。

全面解析使用案例(Use Case)的撰寫與應用

撰寫一份完整的使用案例(Use Case)敘述對於軟體開發、系統設計以及需求分析至關重要。本篇文章將探討使用案例的結構、撰寫方法及其在實際專案中的應用,並透過具體例項進行詳細分析。

使用案例的結構

一個完整的使用案例通常包含以下幾個主要部分:

  1. 使用案例標題與識別碼:如 RCTR_USE_022,用於唯一標識該使用案例。
  2. 相關需求:列出與該使用案例相關的系統需求規格,如 RCTR_SyRS_022RCTR_SRS_022_000
  3. 參與者(Actors):指出與該使用案例互動的角色,例如操作員或系統。
  4. 目標:描述該使用案例的主要目標,例如選擇自動操作期間使用的功率測量通道。
  5. 假設與前置條件:列出執行該使用案例前必須滿足的條件,例如操作員已登入反應堆積控制檯。
  6. 觸發條件:描述啟動該使用案例的事件,例如操作員按下按鈕選擇自動模式電源。
  7. 終止條件:說明該使用案例的結束狀態,例如系統使用選定的功率源進行自動操作。
  8. 後置條件:描述該使用案例完成後系統的狀態,例如系統具備可用的自動模式功率源。

事件流程與替代流程

使用案例的事件流程(Flow of Events)描述了系統在正常情況下如何回應使用者的操作。例如,在 RCTR_USE_022 使用案例中,事件流程如下:

  1. 操作員按下 NP 選擇按鈕。
  2. 系統驗證 NP 是否線上。
  3. 系統切換自動模式功率選擇至 NP 通道。

事件流程表格範例

| 步驟 | 動作描述 | |


|



| | 1 | 操作員按下 NP 選擇按鈕 | | 2 | 系統驗證 NP 是否線上 | | 3 | 系統切換至 NP 通道 |

替代流程(Alternative Flow of Events)則描述了當事件流程中出現異常或條件不滿足時的處理方式。例如,當 NP 通道不線上時,系統不會切換至該通道,而是繼續使用先前選定的通道。

替代流程表格範例

| 步驟 | 動作描述 | |


|



| | 2.1 | NP 通道不線上 | | 2.2 | 系統繼續使用先前選定的通道 |

多重路徑的處理

對於具有多種正確路徑的使用案例,可以透過在事件流程中加入條件分支來處理。然而,這種做法可能會使用案例變得複雜。因此,通常建議為每個主要的正確路徑建立獨立的使用案例。

程式碼範例與解析

以下是一個簡單的程式碼範例,用於示範如何實作 read_port 命令:

def read_port(port_number):
    """
    讀取指定數位資料埠的值。

    :param port_number: 要讀取的埠號
    :return: 埠值或錯誤訊息
    """
    if not isinstance(port_number, int) or port_number < 0 or port_number > 15:
        return "Range Error"
    # 假設有一個函式 _read_digital_data 用於實際讀取資料
    return _read_digital_data(port_number)

# 示例用法
print(read_port(5))  # 正確讀取埠5的值
print(read_port(20)) # 傳回 "Range Error",因為埠號超出範圍

程式碼解析

  1. read_port 函式:接收一個引數 port_number,代表要讀取的埠號。
  2. 輸入驗證:檢查 port_number 是否為整數且在有效範圍內(0 至 15)。若否,傳回 “Range Error”。
  3. 資料讀取:呼叫 _read_digital_data 函式讀取指定埠的值(假設此函式已實作)。
  4. 錯誤處理:當輸入無效時,傳回適當的錯誤訊息。

結語

撰寫完整的使用案例敘述能夠有效地捕捉系統需求,並指導開發團隊進行系統設計與實作。透過結合事件流程、替代流程以及適當的條件分支,可以全面地描述系統在不同情況下的行為,從而提高系統的可靠性和可用性。未來,在軟體開發與系統設計中,應持續最佳化使用案例撰寫的方法和實踐,以提升專案的成功率和品質。

UML 與使用案例簡介

使用案例的事件流程與替代流程

在 UML 的使用案例中,事件流程(Flow of Events)描述了系統如何回應使用者的操作。以一個處理 ppdio 命令的例子來說明:

  1. 驗證命令是否以 ppdio 開頭。
  2. 檢查命令列上的第二個單詞是否是 boards
  3. 如果命令列上沒有其他引數,則傳回系統中 PPDIO 板的數量作為回應。
  4. 驗證命令列上是否有單一的數字引數。
  5. 檢查該數字引數是否在 0 到 6 的範圍內。
  6. 將 PPDIO 板的數量設定為該數字引數的值。

事件流程中的條件判斷

在事件流程中使用條件判斷和多個離開點並不是「乾淨」的 UML,但這樣做可以減少整體檔案的大小,從而節省時間和成本。因此,這在實際使用案例中是常見的做法。

if (command.startsWith("ppdio")) {
    if (command.split("\\s+").length > 1 && command.split("\\s+")[1].equals("boards")) {
        // 執行 boards 相關操作
    } else {
        // 傳回錯誤訊息
    }
} else {
    // 傳回非 PPDIO 命令的錯誤訊息
}

內容解密:

  1. 條件檢查:首先檢查命令是否以 ppdio 開頭,然後進一步檢查第二個引數是否是 boards,確保命令格式正確。
  2. 引數處理:根據命令列上的引數數量和型別,決定是傳回當前 PPDIO 板數量還是設定新的數量。
  3. 錯誤處理:對於不符合預期的命令或引數,透過替代流程傳回適當的錯誤訊息。

使用案例的替代流程

替代流程(Alternative Flows)用於處理主流程以外的情況,例如錯誤處理或其他條件分支。

1.1 如果命令不以 ppdio 開頭,則傳回非 PPDIO 命令的錯誤訊息。 2.1 如果命令不是 ppdio boards,則傳回非 PPDIO BOARDS 的錯誤訊息。 5.1 如果數字引數超出範圍,則傳回語法錯誤。 6.1 如果設定失敗,則傳回範圍錯誤。

為何使用替代流程?

雖然替代流程常用於錯誤處理,但也可以用於其他條件分支。然而,將相關的概念分散在主流程和替代流程中可能會使邏輯變得複雜。

一般化與擴充套件的使用時機

在某些情況下,使用一般化(Generalization)比擴充套件(Extension)更合適。例如,當 read_portwrite_portport_command 的特殊情況時,使用一般化會比擴充套件更自然。

圖示說明

此圖示展示了 read_portwrite_port 如何從 port_command 繼承屬性。

內容解密:

  1. 一般化的優點:透過一般化,衍生的使用案例可以遵循基礎使用案例的所有步驟,保持邏輯的一致性。
  2. 擴充套件的限制:使用擴充套件時,控制權會從主流程轉移到替代流程,主流程中的剩餘步驟可能不會被執行。

使用案例場景

場景(Scenario)是指透過使用案例的某條特定路徑。例如,read_port 使用案例有多個場景,包括成功讀取埠資料、語法錯誤和範圍錯誤等。

成功場景示例

  1. 主機傳送以 read_port 開頭的命令。
  2. 系統驗證第二個引數是否存在且為數字字串。
  3. 系統讀取指定埠的資料並傳回給主機。

語法錯誤場景示例

  1. 主機傳送以 read_port 開頭但缺少第二個引數的命令。
  2. 系統傳回語法錯誤訊息。

內容解密:

  1. 場景的多樣性:每個使用案例可以有多個場景,涵蓋不同的執行路徑和結果。
  2. 測試使用案例的生成:透過分析場景,可以生成對應的測試使用案例和測試程式,以驗證系統的功能正確性。

UML 系統邊界圖

UML 系統邊界圖(System Boundary Diagrams)用於清晰地表示系統內部和外部的元件。當有多個系統參與時,這種圖表可以幫助釐清各系統之間的邊界和關係。

為何需要系統邊界圖?

當使用案例圖涉及多個系統或外部角色時,系統邊界圖能夠提供更清晰的視覺表示,說明哪些元件屬於系統內部,哪些是外部實體。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title UML 基礎與使用案例模型解析

package "機器學習流程" {
    package "資料處理" {
        component [資料收集] as collect
        component [資料清洗] as clean
        component [特徵工程] as feature
    }

    package "模型訓練" {
        component [模型選擇] as select
        component [超參數調優] as tune
        component [交叉驗證] as cv
    }

    package "評估部署" {
        component [模型評估] as eval
        component [模型部署] as deploy
        component [監控維護] as monitor
    }
}

collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型

note right of feature
  特徵工程包含:
  - 特徵選擇
  - 特徵轉換
  - 降維處理
end note

note right of eval
  評估指標:
  - 準確率/召回率
  - F1 Score
  - AUC-ROC
end note

@enduml

此圖示展示了系統邊界內的 use case 和外部角色之間的互動。

內容解密:

  1. 清晰的邊界:系統邊界圖幫助開發者清晰地定義系統的範圍和外部介面。
  2. 多系統互動:當涉及多個系統時,系統邊界圖能夠有效地展示各系統之間的關係和邊界。