作業: 指出設計元素
這項作業說明如何識別子系統、類別、介面、事件和信號。
目的
  • 對分析類別的互動進行分析來識別設計模型元素
關係
主要說明

作業:使用案例分析會產生分析類別,這些分析類別代表可以執行行為的概念事物。在設計中,分析類別會發展成許多不同種類的設計元素:

  • 類別,用來代表一組相當精細的責任;
  • 子系統,用來代表一組粗略的責任,可能是由一組子系統進一步組成,但最後是由一組類別組成;
  • 主動類別,用來代表系統中的執行緒;
  • 介面,用來代表類別或子系統所提供之責任的抽象宣告。

另外,在設計中,我們也將識別:

  • 事件,它們是在時空之中,通常會需要系統回應之相關情況(如果它們很顯著)的規格;以及
  • 信號,代表用來溝通系統內某幾類事件的非同步機制。

這些進一步的細分,可讓我們檢查設計的不同方面:

  • 事件及用來溝通事件的信號,可讓我們描述系統必須回應之行為的非同步觸發。
  • 類別和子系統可讓我們將相關責任分組到可相對獨立開發的單元內;當子系統是組合的建置區塊,而這些建置區塊又是類別或其他子系統所組成時,類別用來實現一組不可分割的相關責任。子系統則是以單一整合功能單元來代表開發小組的工作成果,且正因為如此,它們既可用來作為控制和配置的管理單元,也用來作為邏輯設計元素。
  • 主動類別用來代表系統中的控制緒,可用來建立並行模型。一般而言,主動類別會用來結合通常是被動(但不一定是被動)的其他類別:之後,就可以依照協同作業的方式,利用這種組合來建立複雜行為的模型。

    在即時系統中,封裝體用來代替主動類別,它提供更強的語意來簡化設計和增加並行應用程式的可靠性。封裝體會共用類別和子系統這兩者的某些方面:它實際上是封裝起來的類別協同作業,它們共同代表系統中的一段控制緒。它們與子系統的不同之處,在於封裝體是單一設計師的責任,子系統則(通常)是開發人員小組的責任;不過,子系統也可能包含封裝體。 

  • 介面可讓我們檢查和擷取系統的「接縫」,用精確的詞彙來定義系統的組成部分如何交互作業。
  • 在即時系統中,我們將利用通訊協定來精確定義在封裝體的埠上傳送和接收的訊息。

藉由區分各項考量,分別處理這些概念所代表的每個問題,我們便簡化了設計流程,釐清了我們的解決方案。

如果要維護系統模型之間的可追蹤性,便應該在這項作業期間產生文件。如需產生設計模型和其他系統模型之間的可追蹤性文件的相關資訊,請參閱準則:設計模型

 UML 1.x 表示法

根據 UML 1.5 ,子系統實際上是只以介面為公用元素的特殊套件類型。這些介面提供一個用來隱藏子系統內部設計,使其他模型元素無法見到這個設計的封裝層次。子系統概念用來與「一般」套件(也就是不具特定語意的模型元素儲存器)形成區別;子系統代表特定的套件用法,含有與類別相似(行為)的內容。

在 RUP 中,封裝體是利用 UML 1.5 表示法來表示。在 UML 2.0 中,多半可用概念:結構化類別來表示。

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

步驟
識別事件和信號
目的 識別系統必須回應的內部和外部事件和信號。 

事件是在系統內引起某些動作的內部和外部情況。事件及其特性有助於識別主要設計元素,如主動類別。

外部事件的起始清單可以從使用案例模型衍生而來,從參與者和使用案例的互動衍生而來。內部事件可以從使用案例流程中的文字衍生而來,也可以在設計發展時識別出來。

事件的重要特性如下:

  • 內部和外部 - 事件是內部或外部事件?
  • 優先順序 - 是否需要暫停其他處理,才能處理這個事件?
  • 頻率 - 事件的發生頻率如何?
  • 頻率分佈 - 事件是定期發生,或有尖峰的產生?
  • 回應需求 - 系統回應事件的速度必須多快(可能需要區分一般情況和最糟情況)。
  • 類型 - 這是一個呼叫事件、時間事件、信號事件或變更事件?(請參閱概念:事件和信號,以瞭解定義)

您應該依照需要來擷取事件的特性,以便識別處理它們的設計元素。擷取事件特性往往是在反應(事件驅動)系統中最重要,但在其他系統中,它也可能很有幫助,例如含有並行和/或非同步傳訊的系統。

非同步通訊事件可以建模成信號來表示它們所傳送的信號,或表示信號之間的關係,如一般化。在某些系統中,尤其是反應系統,將從外部裝置收到的信號關聯於特定機制(如岔斷或特定輪詢訊息)很重要。

識別類別、主動類別和子系統
目的 分析類別修正成適當的設計模型元素

識別類別。 當分析類別很簡單,且已有了單一抽象的邏輯表現,它就可以透過 1:1 的方式直接對映到設計類別。一般而言,實體類別會相對原封不動地保留到設計中。由於實體類別通常也會持續存在,因此,請判斷設計類別是否應該持續存在,並相應地將它寫在類別說明中。

當識別類別時,應該將它們分組到工作成果:設計套件中,以便進行組織和配置管理。請參閱工作成果準則:設計套件,以取得如何建立套裝決策的相關資訊。

識別主動類別。 請設想系統在所識別的分析物件的環境中之並行要求:系統需要回應外部產生的事件嗎?若是如此,當事件發生時,哪些分析類別是「主動」的? 使用案例模型中的外部事件,是用與使用案例互動的參與者所產生之刺激因素來表示。請查看相對應的使用案例實現化,以瞭解當發生事件時,哪些物件會互動。開始時,是將物件分組到各個自主的協同作業物件集中,這些分組代表可能形成組合式主動類別之群組的起點。

如果事件有必須擷取的重要屬性,請考慮將它們建模成模板為 <<signal>> 的類別。在即時系統中,這些已識別的各組物件應該分組到封裝語意較強的封裝體中。

主動類別的實例代表獨立的「邏輯」執行緒。這些「邏輯」執行緒不能與作業系統中的執行緒相混淆,也不能在字面上對映到作業系統的執行緒(不過,我們有時會將它們對映到作業系統執行緒)。相反地,在解決方案空間裡,它們代表獨立的概念性執行緒。在設計的這個點上,我們識別它們的目標是能夠根據系統中自然的「並行縫」,將解決方案分割成獨立的單元。依照這個方式來區分工作,會使並行處理的問題概念更簡單,因為除了共用基礎被動類別的範圍之外,獨立執行緒可以個別處理。

一般而言,每當問題領域有並行現象存在且並行發生衝突時,都應該考慮主動類別。這時應該利用主動類別來代表某些外部並行物件或電腦內的並行活動。這使我們有能力監視和控制並行活動。

另一個自然選擇是利用主動類別來作為連接電腦之外部實體裝置的內部代表,因為這些實體本來就是並行的。這些「裝置驅動程式」類別不只用來監視和控制對應的實體裝置,他們也用來隔離系統的其餘部分和裝置的細節。這表示即使裝置背後的技術有所發展,系統的其餘部分也不會受影響。

另一個常用主動類別的情況是利用它們來代表邏輯並行活動。邏輯活動代表概念上的並行「物件」,例如金融交易或電話呼叫。儘管事實上這些都不直接表現為實際實體(雖然他們發生在實體世界中),但也經常會有理由依照這個方式來處理他們。例如,我們也許需要暫時抑制特定金融交易來避免並行衝突,我們也可能會因為系統內的失敗而必須放棄它。由於這些概念物件必須當作一個單元來操作,因此,將它們表現成物件且本身含有用來提供適當功能的介面,會很方便。

主動物件控制器便是這類概念物件的特定範例。它的目的是持續管理一或多個其他主動物件。這通常包括使每個物件進入所需要的作業狀態,讓它維持在這個狀態來面對各種毀壞狀況(如局部失敗),以及使它的作業與其他物件的作業同步。這些主動物件控制器通常是從作業:使用案例分析期間所識別的控制物件發展而來。

由於它們能夠簡單而平穩地解決並行衝突,因此,主動類別也可用來監護共用資源。在這個情況下,會將多個並行活動所需要的一或多項資源封裝在主動類別中。藉由內建的互斥語意,這些監護會自動針對並行衝突來保護這些資源。

即時系統應該利用封裝體來代替主動類別:不論您根據上述啟發法,在哪裡識別了對於主動類別的需求,您都應該改用封裝體。

識別子系統。 當分析類別很複雜,因而表現為能夠體現行為(這不是單一類別獨自的責任),分析類別便應該對映到設計子系統。設計子系統用來將這些協同作業封裝起來,使子系統的客戶即便使用子系統所提供的服務,也可以完全不知道子系統的內部設計。

子系統會塑造成只以介面為公用元素的 UML 元件。這些介面提供一個用來隱藏子系統內部設計,使其他模型元素無法見到這個設計的封裝層次。子系統概念用來與套件(也就是不具特定語意的模型元素儲存器)形成區別。

從一組協同作業的分析類別建立子系統的決策,在相當程度上,是以協同作業是否將會或能夠由個別設計小組來獨立開發為基礎。如果協同作業可以與協同作業的類別完全包含在一個套件內,子系統就可以提供比簡單套件還強的封裝形式。子系統內的內容和協同作業完全隔離在一或多個介面之後,因此,子系統的用戶端只相依於介面。因此,子系統的設計者也完全隔離於外部相依性之外;設計者(或設計小組)必須指定介面的實現方式,不過,他們完全可以自由變更內部子系統設計,不會影響外部相依性。在非常獨立的小組所組成的大型系統中,這個分離程度與正式介面所施行的架構結合起來,便是選擇子系統而不選擇簡單套件的有力論據。請參閱工作成果準則:設計子系統,以取得影響利用子系統作為設計元素之選擇的相關因素資訊。

識別子系統介面
目的 識別形成系統內各個縫的設計元素。 

介面會定義一組由某個分類器來實現的作業。在設計模型中,介面主要用來定義子系統的介面。這不表示類別不能使用它們,不過,對於單一類別而言,定義類別的公用作業通常便已足夠(事實上,就是定義它的「介面」)。對子系統而言,介面很重要,因為它們可讓您將行為的宣告(介面)和行為的實現(子系統內實現介面的特定類別)分開。如此分離之後,開發小組將更能夠獨立處理系統的不同部分,同時仍保留這些不同部分之間精確的「合約」定義。

針對每個子系統,各識別一組候選的介面。 請利用上一步驟所識別的各組協同作業來識別在起始協同作業時「啟動」的責任。之後,便判斷「用戶端」必須提供哪些資訊以及協同作業完成時會傳回什麼資訊來修正這個責任;這幾組資訊會成為輸入和輸出參數的原型,以及子系統將實現之作業的回覆值原型。請利用工作成果:專案特定準則中所定義的命名慣例來定義這個作業的名稱。請重複這個步驟,直到定義好子系統將實現的所有作業為止。

之後,根據相關的責任來分組各項作業。群組最好小一點,因為群組中的作業越少,越容易有一組內聚的共有責任。另外,也請注意重複使用 - 請找出類似性,以便更容易識別出可重複使用的相關功能。不過,這時不要花太多時間來嘗試尋找理想的責任分組;請記住,這只是最初步的分組,在詳述階段中,將反覆進行修正。

尋找介面之間的類似性。 從一組候選的介面中,尋找類似的名稱、類似的責任,以及類似的作業。當許多介面有相同的作業時,請重構介面,將共用作業擷取到新的介面中。請務必查看現有的介面,儘可能重複使用它們。目標是在介面之間移除冗餘作業,同時維護介面的內聚性。這會使介面更容易瞭解,且會隨著時間而發展。

定義介面相依性。 每個介面作業的參數和回覆值都有特定類型:它們必須實現特定介面,或必須是簡式資料類型的實例。當參數是實現特定介面的物件時,請定義介面和它依賴的介面之間的相依性關係。定義介面之間的相依性,會提供非常有用的耦合性資訊給軟體架構師,因為介面相依性會定義設計模型各元素之間的主要相依關係。

將介面對映到子系統。 識別了介面之後,請建立子系統和它所實現的介面之間的實現關聯。從子系統到介面的實現會指出子系統內一或多個實現介面作業的元素。稍後,當設計子系統時,會修正這些子系統到介面的實現,子系統設計師將指定子系統內的哪些特定元素會實現介面的作業。只有子系統設計師能夠見到這些修正的實現;從子系統用戶端的角度來看,只能見到「子系統-介面」實現化。

定義介面所指定的行為。 介面通常會針對實現介面的元素來定義一個隱含的狀態機。如果必須依照特定順序來呼叫介面的各項作業(如必須先開啟資料庫連線,才能使用這個連線),您也應該定義一個狀態機來說明實現介面的任何設計元素必須支援的可公開見到(或推斷)的狀態。這個狀態機可協助介面使用者更充分瞭解介面,且可協助實現介面之元素的設計者提供正確的元素行為。

套裝介面。 介面是軟體架構師所擁有的;介面的變更一律含有架構重要性。如果要管理這一點,介面應該分組成軟體架構師所擁有的一或多個套件。如果每個介面都是由單一子系統來實現,介面就可以放在子系統的相同套件中。如果介面是多個子系統所實現,它們應該放在軟體架構師所擁有的個別套件中。這會使介面的管理和控制,能夠在子系統本身之外個別進行。

識別封裝體通訊協定

目的

識別形成系統內各個縫的設計元素(只適用於 RT 設計)。

通訊協定類似於事件驅動系統中的介面:它們會定義一組在獨立控制緒之間用來通訊的相符信號,以識別封裝體之間的「合約」。介面主要是用來定義會用到呼叫的函數呼叫模型之同步傳訊,通訊協定主要用來定義會用到基於信號的傳訊之非同步通訊。通訊協定可讓您將行為的宣告(信號集)和行為的實現(子系統內實現介面的元素)分開。如此分離之後,開發小組將更能夠獨立處理系統的不同部分,同時仍保留這些不同部分之間精確的「合約」定義。

針對各個封裝體,識別一組輸入和輸出信號。 請利用先前的步驟所識別的各組協同作業來識別起始協同作業時所「啟動」的責任。之後,便判斷「用戶端」必須提供哪些資訊以及協同作業完成時會傳回什麼資訊來修正這個責任;這幾組資訊會成為封裝體將利用它的一個埠來實現之信號的輸入參數原型。請利用工作成果:專案特定準則中所定義的命名慣例來定義這個信號的名稱。請重複這個步驟,直到定義好封裝體將實現的所有信號為止。

之後,根據相關的責任來分組各個信號。群組最好小一點,因為群組中的信號越少,越容易有一組內聚的共有責任。另外,也請注意重複使用 - 請找出類似性,以便更容易識別出可重複使用的相關功能。不過,這時不要花太多時間來嘗試尋找理想的責任分組;請記住,這只是最初步的分組,在詳述階段中,將反覆進行修正。請提供有意義的通訊協定名稱,這個名稱要能夠說明通訊協定在封裝體協同作業中扮演的角色。

尋找通訊協定之間的類似性。 從一組候選的通訊協定中,尋找類似的名稱、類似的責任,以及類似的信號。當許多通訊協定有相同的信號時,請重構這些通訊協定,將共用信號擷取到新的介面中。請務必查看現有的通訊協定,儘可能重複使用它們。目標是在通訊協定之間移除冗餘信號,同時維護通訊協定的內聚性。這會使通訊協定更容易瞭解,且會隨著時間而發展。

將通訊協定對映到封裝體。 識別通訊協定之後,請在封裝體上,建立用來實現通訊協定的。封裝體的埠用來定義封裝體的「介面」,也就是可向封裝體要求的行為。稍後,當設計封裝體時,狀態機會針對封裝體來說明埠所指定的行為。

定義通訊協定所指定的行為。 通訊協定通常會針對實現介面的元素來定義一個隱含的狀態機。如果必須依照特定順序來接收介面的各個輸入信號(如必須先收到「系統備妥」信號,才能收到特定錯誤信號),您也應該定義一個狀態機來說明實現通訊協定的任何設計元素所需支援的可公開見到(或推斷)的狀態。這個狀態機可協助實現通訊協定之封裝體的使用者更充分瞭解它們的行為,且可協助封裝體的設計者提供正確的元素行為。

套裝通訊協定。 通訊協定是軟體架構師所擁有的;通訊協定的變更一律含有架構重要性。如果要管理這一點,通訊協定應該分組成軟體架構師所擁有的一或多個套件。這會使通訊協定的管理和控制,能夠在實現通訊協定的封裝體之外個別進行。


內容
多次出現的項目
事件驅動
持續進行中
選用
規劃
可重複的
詳細資訊