作業: 使用案例設計
這項作業定義如何藉由開發設計層次使用案例實現化來修正使用案例分析的成果。
規範: 分析 設計
目的
  • 透過互動來修正使用案例實現化
  • 修正設計類別的作業需求
  • 修正設計子系統和/或它們的介面的作業需求
  • 修正封裝體的作業需求
關係
主要說明

系統的行為可以利用許多技術(協同作業或互動)來說明。這項作業說明如何利用互動(明確地說,就是序列圖)來說明系統的行為。當系統或子系統的行為可利用同步傳訊來進行主要說明時,序列圖最有用。非同步傳訊,尤其是在事件驅動的系統中,通常很容易透過狀態機和協同作業來說明,可讓您利用精簡的方式來定義物件之間所可能有的互動。在即時或反應系統中,非同步傳訊扮演了非常重要的角色,可用來進行 工作成果:封裝體實例之間的通訊。

 UML 1.x 表示法

在序列圖中,您可以利用 Proxy 類別來代表子系統。這個 Proxy 類別包含在子系統內,在圖解中,它用來代表不支援直接以套件和子系統為行為元素的系統。當您要顯示特定子系統回應某項訊息時,請使用 Proxy 類別。在這個情況下,您可以顯示訊息從子系統 Proxy 傳到其他物件。

如需相關資訊,請參閱 UML 1.x 和 UML 2.0 的差異

步驟
建立使用案例實現化

工作成果:設計使用案例實現化提供一種方式,供您將設計模型中的行為追蹤到使用案例模型,它環繞著使用案例概念來組織設計模型中的協同作業。

請在設計模型中,針對要設計的每個使用案例來建立設計使用案例實現化。設計使用案例實現化的名稱應該與相關聯的使用案例相同,它應該建立起從使用案例實現化到相關使用案例的「實現」關係。

說明設計物件之間的互動

您應該針對每項使用案例實現化,建立一或多個序列圖來說明參與的設計物件之間的互動。這些項目的早期版本應該是在作業:使用案例分析期間建立的。使用案例實現化的這類「分析版本」會說明分析類別之間的互動。它們需要發展成能夠說明設計元素之間的互動。

更新序列圖包含下列步驟:

  • 識別各個參與使用案例流程的物件。這是藉由建立作業:識別設計元素中所識別之設計類別和子系統的實例來完成的。在即時系統中,您也將識別參與使用案例流程的封裝體實例。
  • 在序列圖中呈現每個參與的物件。在序列圖中,每個參與的物件都要畫一條生命線。如果要呈現設計子系統,您可以有幾個選擇:
    • 您可以在序列圖中顯示子系統的實例。
    • 您可以使用子系統所實現的介面。當您想要表示實現相同介面的任何模型元素都可用來取代介面時,便很適合這個方式。如果您選擇在序列圖中顯示介面,請注意,您會想要確定不會有任何從介面送往其他物件的訊息。原因在於介面會將作業的內部實現完全封裝起來。因此,我們無法確定實現介面的所有模型元素實際上都是用相同方式來設計。因此,序列圖不應顯示從介面送出的任何訊息。
    • 在序列圖中,您可以利用元件來代表子系統。當您要顯示特定子系統回應某項訊息時,請使用元件。在這個情況下,您可以顯示訊息從元件傳到其他物件。

    請注意,這些都是系統層次的序列圖,它顯示最上層設計元素(通常是子系統和子系統介面)的實例如何互動。顯示子系統內部設計的序列圖是在作業:子系統設計中個別產生。

  • 請注意,主動物件互動通常是利用規格協同作業和狀態機來說明。這裡利用它們來顯示在較大型的使用案例實現化中,系統中的其他元素可如何將訊息傳給主動物件。在典型用法中,為了這項作業的目的,主動物件是封裝在子系統中,因此,使用案例實現化是由一組互動的子系統組成。互動定義了子系統的責任和介面。在子系統內,主動物件代表並行執行緒。子系統可讓您在開發小組之間分割工作,以介面作為小組之間的正式合約。如果是即時系統,您會利用 工作成果:封裝體來代表主動物件。

    顯示從子系統發出的訊息之次要附註:將訊息限制於介面,會降低模型元素之間的耦合性,增進設計的彈性。可能的話,您應該嘗試做到這一點,如果有從子系統送往非介面模型元素的訊息,您應該找機會將它們改成送往介面的訊息,以改進模型中的分離。

  • 呈現與參與者的互動。請利用序列圖中的生命線來呈現參與的物件所互動的每個參與者實例和外部物件。
  • 說明在參與的物件之間傳送的訊息。事件流程從圖的頂端開始向下進行,表示一個垂直的時間軸。請在生命線之間建立訊息(箭頭)來說明在物件之間傳送的訊息。訊息的名稱應該就是訊息所呼叫的作業名稱。在設計的早期階段中,不會指派很多作業給物件,因此,您可以省略這項資訊,提供暫時的名稱給訊息;這類訊息稱為「未指派」的訊息。稍後,當您發現更多參與物件的作業時,您應該搭配這些作業來「指派」訊息,以更新序列圖。
  • 說明當物件收到訊息時,它會做什麼。這是藉由將 Script 附加到對應的訊息來完成的。 請將這些 Script 放在圖的邊距上。請使用結構化的文字或虛擬程式碼。如果您使用虛擬程式碼,請務必使用實作語言中的各項限制,使對應作業的實作簡單一些。當物件類別的負責人指派和定義它的作業時,物件的 Script 會提供這項工作的基礎。

圖解說明詳見隨附的文字。

您在序列圖中,產生物件所執行之使用案例行為的文件。

在物件之間散佈行為之後,您應該考慮如何控制流程。您假設在使用案例實現化中,物件會以特定方式來互動且有特定角色,因而發現物件。當您散佈行為時,您可以開始測試這些假設。在流程的某些部分中,您可以使用分散式結構;在其他部分中,您可能會偏好集中式結構。如需這些變式的定義及何時使用這兩類結構的建議,請參閱技術:序列圖

這時您可能需要新物件,例如,您使用集中式結構,且需要新物件來控制流程。請記住,您加入設計模型的任何物件都必須滿足在物件模型上所設定的需求。

納入適用的設計機制

作業:架構分析期間,會識別分析機制。在作業:識別設計機制期間,會將分析機制修正成設計機制,從分析機制到設計機制的對映擷取在軟體架構文件中,設計機制的說明在 特定專案專用的準則中。  

在這項作業期間,使用案例設計、任何適用的設計機制都會納入使用案例實現化中。設計者會在軟體架構文件和設計準則所說明的建議和準則內運作,調查可用的設計機制,判斷開發中的使用案例實現化所適用的設計機制。  
附註:適用的設計機制可能已識別在作業:使用案例分析中,在這期間,分析類別可能已「標示」了特定分析機制,指出一段必須在設計中處理的特定功能。在這種情況下,適用的設計機制是關聯於參與使用案例實現化的分析類別所標示之分析機制的設計機制。

設計者將遵循設計準則所說明的使用規則,將必要的設計元素和設計元素互動併入使用案例實現化中,以將適用的設計機制納入使用案例實現化中。

處理事件流程的所有變式

您應該在個別序列圖中說明每個流程變式。一般而言,序列圖比通訊圖好用,因為當這個圖必須包含我們在設計系統時通常會想併入的細節層次時,它們往往比較容易閱讀。

首先,請說明基本流程,它是最一般或最重要的事件流程。之後,再說明例外流程之類的變式。只要您使用參與物件的所有作業,以範例示範了這些作業,就不需要說明所有事件流程。在這個情況下,您可以省略無關緊要的流程,例如,只涉及單一物件的流程。

請研究使用案例,以瞭解在需求擷取和分析所說明的流程變式之外,還有沒有其他流程變式,例如會依賴實作的流程變式。當您識別新流程時,請在序列圖中,說明每個流程。例外流程的範例包括:

  • 錯誤處理。如果介面報告發生錯誤,例如,它與某個外部系統的通訊出錯,使用案例應該處理這個情況。可能的解決方案是開啟一個新的通訊路徑。
  • 逾時處理。如果使用者未在特定期間內回覆,使用案例應該採取某些特殊測量。
  • 處理參與使用案例之物件的錯誤輸入。這類錯誤可能是不正確的使用者輸入所造成。

處理使用案例的選用部分

您可以將流程的替代路徑描述成選用的流程,而不是變式。下列清單包含選用流程的兩個範例。

  • 藉由傳送信號,參與者會從許多選項中,決定使用案例接著要做什麼。例如,使用案例已要求參與者用是或否來回答問題,或提供系統在使用案例現行狀態中所能執行的各種功能給參與者。
  • 流程路徑會隨著儲存的屬性或關係的值而不同。後續事件流程會隨著要處理的資料類型而不同。

如果您想要使某個選用的流程或任何複雜的子流程特別引人注意,請使用個別的序列圖。您應該從主要事件流程的序列圖中,利用 Script、邊距文字或附註來指示發生選用或子流程行為的位置,以便參照每個個別的序列圖。

當隨處都可能發生選用或例外的流程行為時,例如發生特定事件時所執行的行為,主要事件流程的序列圖應該利用註解來指出,當發生事件時,將執行選用/例外序列圖中所說明的行為。另外,如果有重要的事件驅動行為,請考慮利用狀態圖來描述系統行為。如需詳細資訊,請參閱準則:狀態圖

利用子系統來簡化序列圖(選用)

當實現使用案例時,通常會透過執行物件來說明事件流程,也就是說,將它們當作設計物件之間的互動來說明。如果要簡化各個圖及識別可重複使用的行為,您可能需要將事件子流程封裝在子系統內。完成這個動作之後,就會用對子系統的單一訊息來取代序列圖的大型子區段。在子系統內,個別的序列圖可以說明子系統內提供必要行為的內部互動(如需相關資訊,請參閱作業:子系統設計)。

在下列情況下,序列圖內訊息的子序列應該封裝在子系統內:

  • 子序列在不同使用案例實現化中重複出現;也就是說,相同(或類似)訊息會傳給相同(或類似)物件,提供相同的最終結果。使用「類似」一詞是因為有些設計工作可能需要使行為可重複使用。
  • 子序列只出現在單一使用案例實現化中,但在未來的反覆或類似系統中,它應該會重複執行。這個行為可以形成很好的可重複使用的元件。
  • 子序列只出現在單一使用案例實現化中,但它既複雜又容易封裝,必須由一個人或一個小組來負責,它會提供定義好的結果。在這類情況中,複雜行為通常需要特殊技術知識,或特殊領域知識,因此它非常適合封裝在子系統內。
  • 判斷要將子序列封裝在可取代的元件內(請參閱概念:元件)。在這個情況下,子系統是元件在設計模型內的適當表示法。

圖解說明詳見隨附的文字。

必要的話,您可以在子系統階層的許多層次說明使用案例實現化。中間圖中的生命線代表子系統;圓圈中的互動代表子系統成員回應訊息的內部互動。

這種方式的好處如下:

  • 使用案例實現化會比較不雜亂,當部分子系統的內部設計很複雜時,尤其如此。
  • 在建立子系統內部設計之前,就可以建立使用案例實現化;這非常有用,例如在並列開發環境中便是如此(請參閱如何平行運作)。
  • 使用案例實現化會成為更通用,更容易變更,當必須用另一個子系統來替代子系統時,尤其如此。

範例:

請考量下列序列圖,它是區域電話使用案例實現化的一部分:

圖解說明詳見隨附的文字。

在這個圖中,灰色類別屬於網路處理子系統;其他類別屬於訂閱者處理子系統。這隱含著它是多子系統的序列圖,也就是說,這個圖包含所有參與事件流程的物件,不論它們的類別是否在不同子系統中。

另外,我們也可以選擇顯示網路處理子系統的行為呼叫,以及這個子系統特定介面的操作。我們假設網路處理子系統提供 ICoordinator 介面,訂閱者處理子系統則使用這個介面:

圖解說明詳見隨附的文字。

ICoordinator 介面是網路處理內的 Coordinator 類別所實現的。在這個情況下,我們可以在序列圖中使用網路處理子系統本身和它的 ICoordinator 介面,而不用網路處理內的類別實例:

圖解說明詳見隨附的文字。

請注意,Coordinator、Digit Information 和 Network 類別實例都由它們所在的子系統來加以替代。對於子系統的所有呼叫,都改成透過 ICoordinator 介面來完成。

在生命線顯示介面

為了使實現相同介面的子系統達到真正的可替代性,在互動中(通常在各個圖解中)應該只能見到它們的介面;否則,當子系統互相替代時,就必須變更互動(或圖解)。

範例:

在序列圖中,我們只能併入 ICoordinator 介面,但不能併入提供的子系統:

圖解說明詳見隨附的文字。

將訊息傳到介面生命線,表示實現介面的任何子系統都可以替代圖中的介面。請注意,ICoordinator 介面生命線並沒有從它送出的訊息,因為實現介面的不同子系統可能會傳送不同的訊息。不過,如果您要說明應該(或可以)從實現介面的任何子系統送出哪些訊息,這些訊息可以從介面生命線出去。

如何平行運作

在某些情況下,可能適合在或多或少的獨立程度上,平行於其他子系統來開發子系統。如果要做到這一點,我們必須先識別子系統之間的互動來尋找子系統的相依性。

您可以依照下列方式來執行這項工作:

  1. 集中於會影響子系統互動的需求。
  2. 概述所需要的介面,顯示將通過子系統邊界的訊息。
  3. 就每個使用案例的子系統來繪製序列圖。
  4. 修正提供訊息所需要的介面。
  5. 並列開發每個子系統,利用介面作為開發小組之間的同步化工具。

您也可以選擇要透過子系統,或只透過子系統的介面,來安排序列圖。在部分專案中,您甚至必須先實作提供介面的類別,之後,才能繼續其餘建模程序。

說明持續性相關行為

物件導向參照範例的整體目標是將實作細節封裝起來。因此,關於持續性,我們會想要有一個看起來就像暫時物件的持續性物件。我們應該不需要知道物件會持續存在,或不需要用不同於其他物件的方式來處理它。至少這就是目標所在。

實際上,應用程式有時可能需要控制持續性的各個方面:

  • 何時讀取和寫入持續性物件
  • 何時刪除持續性物件
  • 如何管理交易
  • 如何實現鎖定和並行控制

撰寫持續性物件

這裡有兩個情況必須考量:物件寫入持續性物件儲存庫的起始時間,以及應用程式要利用物件的變更來更新持續性物件儲存庫的後續時間。

不論任何一種情況,特定機制都會隨著持續性架構所支援的作業而不同。一般而言,這個機制用來將訊息傳給持續性架構,以建立持續性物件。物件持續存在之後,持續性架構很聰明,它會偵測出持續性物件的後續變更,必要時,會將這些變更寫入持續性物件儲存庫中(通常是在確定交易之時)。

以下顯示正在建立的持續性物件範例:

圖解說明詳見隨附的文字。

PersistenceMgr 物件是 VBOS 的實例,是一個持續性架構。OrderCoordinator 藉由將 Order 當作 'createPersistentObject' 訊息的引數傳給 PersistenceMgr 來建立持續的 Order。

除非您知道會在某事件序列的特定點上明確儲存物件,否則,通常不需要明確建立這個模型。如果後續作業必須查詢這個物件,物件就必須在資料庫中,因此,必須知道物件會在其中,這一點很重要。

讀取持續性物件

在應用程式將訊息傳送給持續性物件之前,必須先從持續性物件儲存庫中擷取這些物件。請回想一下,在物件導向系統中,是藉由將訊息傳給物件來執行工作。但如果訊息要送往的物件是在資料庫中,而不是在記憶體中,這時會發生問題:您無法將訊息傳給尚不存在的東西!

簡言之,您必須將訊息傳給知道如何查詢資料庫的物件,請擷取正確的物件,建立它的實例。之後,也只有在這時,您才可以傳送原來想傳送的訊息。建立持續性物件實例的物件,有時稱為 Factory 物件。Factory 物件負責建立物件的實例,持續性物件也包括在內。在取得查詢之後,就可以將 Factory 設計成會傳回一組符合查詢的一或多個物件。

一般而言,物件會透過關聯而豐富地連接到其他物件,因此,您通常只需要擷取物件圖中的物件;透過根物件與其餘項目的關聯,基本上,便會以透通方式從資料庫中「拉出」這些部分。(好的持續性機制在這方面很聰明:它只會在必要之時擷取物件;否則,我們可能會不必要地試著建立大量物件的實例。在仍不需要物件之前擷取物件,是過度簡單的持續性機制所造成的主要效能問題之一。)

下列範例顯示從持續性物件儲存庫中擷取的物件如何建模。在實際的序列圖中,不會顯示 DBMS,因為它應該封裝在 Factory 物件中。

圖解說明詳見隨附的文字。

刪除持續性物件

持續性物件的問題就在於它們持續存在! 暫時物件在建立它們的程序結束時便會消失,但持續性物件並不是這樣,它們會持續存在到明確刪除為止。因此,當不再使用持續性物件時,刪除它很重要。

問題是,這很難判斷。原因只在於一個應用程式用完某個物件,並不代表現在和未來的所有應用程式都不再用它。因為物件可能會有它們並不知道的關聯,也確實有這種關聯,有時候就是很難判斷刪除某個物件會不會有問題。

在設計中,這可以利用狀態圖來表達語意:當物件到達結束狀態,便可以說它即將被釋放。之後,負責實作持續性類別的開發人員就可以利用狀態圖資訊呼叫適當的持續性機制行為來釋出物件。使用案例實現化設計者的責任是在適合刪除物件時,呼叫適當的作業,使物件到達它的結束狀態。

如果物件連接許多其他物件,可能很難判斷物件能不能刪除。由於 Factory 物件知道物件的結構,也知道它所連接的物件,因此,要求類別的 Factory 物件負責判斷能不能刪除某個特定實例,通常會很有幫助。持續性架構也可以支援這項功能。

建立交易建模型

交易會定義一組不可分割的作業呼叫;它們若非全部執行,就是全都不執行。在持續性環境中,交易會定義一組物件的一組變更,這些變更若非全部執行,就是全都不執行。交易會提供一致性,以確保各組物件會從某個一致狀態進入另一個一致狀態。

在使用案例實現化中顯示交易有若干選項:

  • 使用文字。您可以利用序列圖邊距中的 Script,依照下圖所示來說明交易界限。這個方法很簡單,可讓您利用任意數量的機制來實作交易。

圖解說明詳見隨附的文字。

利用文字註解來呈現交易界限。

  • 使用明確訊息。如果所用的交易管理機制利用明確訊息來起始和結束交易,就可以依照下圖所示,在序列圖中明確顯示這些訊息:

圖解說明詳見隨附的文字。

顯示啟動和停止交易的明確訊息。

處理錯誤狀況

如果無法執行交易所指定的所有作業(通常是因為發生錯誤),交易就會中止,這時會反向執行交易期間所進行的所有變更。預期的錯誤狀況通常代表使用案例中的例外事件流程。在其他情況下,出現錯誤狀況是因為系統作業失敗。錯誤狀況也應該寫在互動之中。簡單的錯誤和異常狀況可以顯示在它們所出現的交易中;複雜錯誤和異常狀況可能需要它們自己的互動。

特定物件的失敗模式可以顯示在狀態圖中。這些失敗模式的條件式控制處理流程可以顯示在發生錯誤或異常狀況的互動中。

處理並行控制

並行用來說明在交易過程中重要系統資源的存取控制。為了使系統保持一致狀態,交易可能需要獨佔性存取系統中的某些重要資源。獨佔性可包括讀取一組物件、寫入一組物件,或讀寫一組物件的能力。

我們來看一下為什麼需要限制存取一組物件的簡單範例。假設我們在執行一個簡單的訂單項目系統。人們打電話進來下訂單,我們再處理訂單,將訂單出貨。我們可以將訂單看成一種交易。

為了說明關於並行控制的需求,比方說,我打電話進來訂購一雙新的登山鞋。當訂單進入系統時,它會檢查庫存中有沒有我需要的登山鞋,大小必須正確。如果有,我們會想預訂這雙靴子,以免在訂單出貨之前被別人買走。在訂單出貨之後,會從庫存中移除這雙靴子。

下單和出貨隔了一段時間,這時靴子是在特殊狀態,它們在庫存中,但它「已確定」給我的訂單。如果我的訂單因故取消(我改變主意,或我的信用卡過期),這雙靴子就會回到庫存中。訂單出貨之後,我們假設我們的小公司不想保留它曾經有靴子的記錄。

並行的目標和交易一樣,是確定系統會從某個一致狀態進入另一個一致狀態中。另外,並行也會致力確保它完成工作所需要的所有資源。並行控制可利用許多不同的方式來實作,其中包括資源鎖定、號誌、共用記憶體鎖和私密工作區。

在物件導向系統中,只是從訊息型樣中,很難得知特定訊息可不可能造成物件的狀態變更。另外,採用不同的實作,某些資源類型可能就不需要存取限制;例如,有些實作會在各項交易開始之時,提供交易本身的系統狀態觀點。在這個情況下,其他程序可能會變更物件的狀態,但不會影響任何其他現有執行中之交易的「觀點」。

為了避免限制實作,在設計之中,我們只想指示交易必須獨佔性存取的資源。我們要用先前的範例來指示我們需要獨佔性存取的已訂購的鞋子。註解所傳送之訊息的說明來指示應用程式需要獨佔性存取物件,便是一個簡單的選擇方案。之後,實作者就可以利用這項資訊來判斷如何最恰當地實作並行需求。以下顯示序列圖範例,圖中有哪些訊息需要獨佔性存取的註解。假設在交易完成時,釋出所有鎖定。

圖解說明詳見隨附的文字。

在序列圖中顯示註解的存取控制之範例。

交易所需要的所有物件並非全部都有存取限制,原因在於通常只有少數物件應該有存取限制;限制存取參與交易的所有物件,會浪費珍貴的資源,且會造成效能瓶頸,而不是防止效能瓶頸。

修正事件流程說明

在使用案例實現化的事件流程中,您可能需要在序列圖中新增其他說明,以預防只是檢查在參與物件之間傳送的訊息,並無法完全清楚事件流程的情況。例如,為了使外部觀察者更容易讀懂這個圖,您會需要計時註解、條件式行為的附註,或需要澄清作業行為。

事件流程最初的概述在作業:使用案例分析中。在這個步驟中,您依照需要來修正事件流程,使序列圖更加清楚。

作業名稱通常並不足以用來瞭解執行作業的原因。您可能需要利用圖解邊距中的文字附註或 Script 來澄清序列圖。您也可能需要利用文字附註和 Script 來呈現決策步驟、迴圈和分支之類的控制流程。另外,您也可能需要利用文字標示,將使用案例中的延伸點關聯於序列圖中的特定位置。

這項作業先前的範例說明了許多註解序列圖的不同方式。



統一設計類別和子系統

當實現使用案例時,您必須統一所識別的設計類別和子系統,以確定設計模型中的同質性和一致性。

請注意下列各點:

  • 模型元素的名稱應該能夠描述它們的功能。
  • 避免類似的名稱和同義字,因為這會使模型元素難以區分。
  • 請合併定義類似行為或代表相同現象的模型元素。
  • 請合併代表相同概念或有相同屬性的實體類別,即使它們的定義行為不同也一樣。
  • 請利用繼承來使模型元素抽象化,這往往會使模型更強韌。
  • 當更新模型元素時,也請更新使用案例實現化的對應事件流程說明。
評估結果

在這個階段,您應該檢查設計模型來驗證您的工作方向是否正確。您不需要詳細審查模型,但您在處理設計模型時,應該考量它。

請特別參閱作業:審查設計中的使用案例實現化

詳細資訊