子系統可利用多種互補的方式,將系統分割成具有下列功能的單元:
-
能夠個別訂購、配置或交付
-
只要介面維持不變,便能夠個別開發
-
可以獨立部署在一組分散的運算節點上
-
可以個別變更,不會損壞系統的其他部分
因此,子系統是理想的建模元件,建模元件比單一設計類別大,在以元件為基礎的開發中,它們是可取代的組合單元。
另外,子系統還可以:
-
將系統分割成幾個單元,可在主要資源上提供有限的安全
-
在設計中,代表現有的產品或外部系統。
如果複雜的分析類別表現為能夠體現行為(這不是單一設計類別獨自的責任),它便對映於設計子系統。如果複雜的設計類別有可能當作一組協同作業的類別來實作,它也可以成為子系統。
另外,對於個別小組要獨立開發的系統組件,子系統也是一個好的識別方法。如果協同作業的設計元素可以與它們的協同作業完全包含在一個套件內,子系統就可以提比簡單套件提供較強的封裝形式。子系統內的內容和協同作業完全隔離在一或多個介面之後,因此,子系統的用戶端只相依於介面。因此,子系統的設計者也完全隔離於外部相依性之外;設計者(或設計小組)必須指定介面的實現方式,不過,他們完全可以自由變更內部子系統設計,不會影響外部相依性。在大部分獨立的小組所組成的大型系統中,這個分離程度與正式介面所施行的架構結合起來,便是選擇子系統而不選擇簡單套件的有力論據。
設計子系統用來將這些協同作業封裝起來,使子系統的客戶即便使用子系統所提供的服務,也可以完全不知道子系統的內部設計。如果參與協同作業的類別/子系統只是彼此互動,以產生一組定義好的結果,這項協同作業和協同作業的設計元素便應該封裝在子系統內。
這個規則也適用於協同作業的子集。在任何可以封裝和簡化協同作業的部分或全部之處,這麼做都會使設計更容易瞭解。
提示
提示
|
詳細資訊
|
尋找選用性
|
如果特定協同作業(或子協同作業)代表選用的行為,請將它含括在子系統中。可以移除、升級或用替代項目來取代的特性,應該被視為獨立特性。
|
查看系統的使用者介面。
|
如果使用者介面相對地獨立於系統中的實體類別之外(也就是說,這兩者可以,也將會,在互不相關的情況下變更),請建立水平整合的子系統:將相關的使用者介面界限類別一起放在某個子系統中,將相關的實體類別一起放在另一個子系統中。
|
如果使用者介面和它顯示的實體類別緊密耦合(也就是說,一方的變更會觸發另一方的變更),請建立垂直整合的子系統:將相關的界限和實體類別含括在共用子系統中。
|
查看參與者
|
將兩個不同的參與者所用的功能分開,因為每個參與者都可能獨立地變更它們的系統需求。
|
請建立子系統來封裝外部系統或裝置的存取功能。
|
尋找設計元素之間的耦合性和內聚力
|
高度耦合性或凝聚的類別/子系統會協同作業來提供某組服務。
請將高度耦合性的元素組織在子系統中,沿著弱耦合性的軌道,將元素分開。在某些情況下,將類別分割成較小的類別,讓小類別承擔凝聚性更強的責任,或重新適當分割子系統,可以將弱耦合性完全消除。
|
查看替代
|
如果針對特定功能指定了許多服務層次(例如:高、中和低層可用性),請用個別子系統來代表每個服務層次,每個服務層次都用來實現同一組介面。如此一來,子系統便能夠替換另一個子系統。
|
查看分散
|
雖然特定子系統可以有多個實例,每個實例可執行於不同的節點,但在許多架構中,元件的單一實例並不可能分割跨越不同的節點。當子系統行為必須分割跨越不同的節點時,建議您將子系統分解成只包含有限功能的較小子系統(每個都代表單一元件)。
請判斷必須在每個節點的功能,建立一個新的子系統來「擁有」這個功能,適當分散原始子系統的各項責任和相關元素。
新的子系統在原始子系統內部。
|
將設計組織成子系統之後,請據此來更新使用案例實現化。
設計子系統模型是利用 UML 元件來建立的。這項建構提供下列建模功能:
-
可以分組類別來定義系統較粗大的部分
-
可以將可見的介面和內部實作分開
-
可以在執行時期執行
另外,還有一些其他考量:
-
每個設計子系統都必須有名稱和簡要說明。
-
原始分析類別的責任應該轉交給新建的子系統,利用子系統的描述來說明責任
附註:UML 2.0 也定義了名稱為 <<subsystem>> 的元件模板,表示這可用來例如代表規模較大的結構。RUP 設計子系統不一定是大尺度的結構;它們都是 RUP
視景下的設計子系統。這是一個有待決定的軟體架構問題(例如,是否選擇將元件組成的元件標示為 <<subsystem>>)。
當現有產品會匯出介面,也就是作業(可能也包括接收),但會將所有實作細節隱藏起來,在邏輯的觀點下,它便可以建模成子系統。您可以用子系統來表示的系統所用產品範例包括:
-
通訊軟體(中介軟體)。
-
資料庫存取支援(RDBMS 對映支援)。
-
特定應用程式專用的產品。
有些現有產品,例如類型和資料結構的集合(如反覆、清單、佇列),因為不只顯示行為,所以可能比較適合用套件來表示,套件本身只是儲存器而已,重要而且有用的是套件的特定內容,而不是套件本身。
如果一般公用程式(如數學程式庫)只是匯出介面,它們便可以用子系統來表示,但是否必要或有沒有意義,則取決於設計者對於建模事物本質的判斷。子系統是物件導向的建構(因為它們是建模元件):子系統可以有實例(如果設計者如此指示的話)。UML
提供了公用程式中廣域變數和程序群組的另一個建模方式,公用程式是類別的模板,本身並沒有實例。
當定義子系統來代表產品時,另外也請定義一或多個介面來代表產品介面。
設計子系統(模型是 UML 元件)的語意與套件不同:子系統利用它所實現的一或多個介面來提供行為。套件不提供行為;它們只是提供行為之事物的儲存器而已。
利用子系統來取代套件的原因,是子系統會封裝它們的內容,且只透過它們的介面來提供行為。它的好處在於,只要子系統介面維持不變,子系統的內容和內部行為就可以自由變更,這與套件不同。另外,子系統也提供了「可取代的設計」元素:任意兩個實現相同介面的
<<realization>> 元件(或 <<specification>> 元件)都是可交換的。
為了確保子系統是模型中可取代的元素,以下是一些必須實施的規則:
-
子系統應該儘可能避免顯露內容。理想上,子系統不應該有可見性是 'public' 的元素,也因此子系統外也不會有任何元素相依於子系統內特定元素的存在。以下是一些例外:
-
在某些技術中,子系統的外表不能建模成 UML 介面。例如,Java 介面便建模成模板類別。
-
子系統設計可能需要顯露類別,而非 UML 介面。例如,"delegate" 或 "access" 類別可用來隱藏其他類別複雜的協同作業。當可以改用一般套件時,可以利用子系統來強調封裝行為和隱藏內部細節的目的。
-
當子系統的外表不是 UML 介面時,用圖解來顯示子系統的可見元素,通常會有幫助(例如,命名為「外部視圖」)。
-
子系統應該定義它對於子系統介面的相依性(以及上面所說明的例外狀況中子系統的公開可見元素)。另外,許多子系統可能會共用一組介面或類別定義,這時這些子系統會「匯入」包含共用元素之套件的內容。在架構較低層的套件中,這比較常見,可確保已一致地定義了必須在子系統之間傳遞的共用類別定義。
以下是子系統和套件相依性範例:
設計模型中的子系統和套件相依性
UML ([UML04]) 指出:
UML 有許多適用於元件的標準模板(如 <<specification>> 和
<<realization>>),它們可以利用明確的規格和實現化定義來建立元件模型,一個規格可以有多項實現化。
<<specification>> 所模板的元件會指定一個物件領域,但不會定義這些物件實體的實作。它只會有提供的介面和必要的介面,它並不意圖在定義中擁有任何實現化類別或子元件。
<<realization>> 所模板的元件會指定一個物件領域,且會定義這些物件實際的實作。例如,<<realization>> 所模板的元件只會有實作個別的
<<specification>> 元件所指定之行為的實現化類別和子元件。
將規格和實現化分開,基本上,便能夠接受子系統的兩個分開的說明。規格用來作為合約,定義客戶使用子系統時,必須知道的所有項目。實現化是專用來指引實作者的詳細內部設計。如果您要支援多重實現化,請建立個別的「實現化」子系統,從每個實現化子系統繪製一道指向規格子系統的實現化。
如果子系統的內部狀態和行為相當簡單,只用顯現的介面、說明行為的狀態圖及描述性文字來指定子系統,可能已經足夠。
如果是較複雜的內部狀態和行為,您可以利用分析類別來指定高抽象層次的子系統。 如果是系統的大型系統,子系統的規格也可以包含使用案例。請參閱利用 Rational Unified Process 開發大型系統。
在下列情況下,在實現化之外提供詳細規格,可能會特別有用:
-
子系統實現化的內部狀態或行為非常複雜,而規格的表達卻必須儘可能簡單,以便客戶能夠有效使用它:
-
子系統是可重複使用的「組合元件」,專用來組合在許多系統中(請參閱概念:元件);
-
預期子系統的內部將由其他組織來開發;
-
必須建立子系統的多重實作;
-
預期子系統將被另一個版本取代,這個版本內部有大量的變更,但外部的可見行為維持不變。
不過,維護個別規格要費工夫,因為這時必須確定子系統的實現化符合規格。何時及是否建立個別規格和實現化類別及協同作業的準則,應該定義在工作成果:專案專用準則中。
規格應該定義它的相依性。這些都是在子系統的所有標準實現化中,必須能夠使用的其他子系統和套件中的介面和可見元素。
實現化可能會有設計者或實作者所引進的其他相依性。例如,您有時會有機會利用公用程式元件來簡化實作,但這個公用程式元件的使用是客戶不需知道的細節。這些額外的相依性應該擷取在個別圖解中,作為實現化的一部分。
完整的詳細規格用來定義客戶使用子系統時所需要的所有東西。這表示修正顯露的介面及任何公開可見的元素,使它們與程式碼有一對一的關係。引進用來指定子系統行為的分析類別應該維持高階的抽象,因為它們要獨立於任何子系統實作之外。
子系統的實現元素應該緊密對齊程式碼。
請參閱技術:從設計對映至程式碼,以取得這個主題進一步的討論。
建模
設計子系統的模型可以建立成 UML 2.0 元件或 UML 1.5 子系統。這些建構提供的建模功能,與模組化、封裝,和實例在執行時期能夠執行的功能幾乎相等。
以下是這些建模選項的一些其他考量:
-
UML 1.5 子系統明確併入了「規格」和「實現化」(上面標題為子系統規格和實現化的一節中所定義)的觀念。UML 2.0
元件支援規格(形式為一或多個已提供且必要的介面)和實現化(一或多個類別及實現其行為的子元件所組成的內部實作)的概念。
-
另外,UML 1.5 子系統也是套件。UML 2.0 元件有套裝功能,這表示它們可以擁有和匯入可能非常大的一組模型元素。
不過,總的來說,這些觀念可以交換使用。要用 UML 1.5 子系統或 UML 2.0 元件來表現設計子系統是一項決策,應該在專為了您的專案而調整的專案專用準則中提供說明。
如果您的視覺化建模工具支援 UML 1.5 套件而不支援 UML 1.5 子系統,您可以利用模板為 <<subsystem>> 的套件來表示子系統。
子系統相依性限制
標題為子系統相依性限制一節所提及的相同相依性限制和討論,也適用於模型建立成 UML 1.5 子系統的設計子系統。
以下是 UML 1.5 中的子系統和套件相依性範例:
設計模型中的子系統和套件相依性
子系統的規格和實現化
UML 1.5 指出:
子系統的內容分成兩個子集:1) 規格元素和 2) 實現化元素。規格元素與系統的作業和反應,共同用來為實現化元素所提供的行為給予抽象規格。實現化元素的集合用來建立實體系統之行為單元內部的模型。
將規格和實現化分開,基本上,便能夠接受子系統的兩個分開的說明。規格用來作為合約,定義客戶使用子系統時,必須知道的所有項目。實現化是專用來指引實作者的詳細內部設計。
如果建模環境不直接支援的話,建模規格和實現化的一個選項是將規格和實現化這兩個套件放在每個子系統中。
規格的一項動機是支援多重實現化。UML 1.x 並不直接提供這項支援。如果您要利用 UML 1.5 子系統來支援多重實現化,請建立個別的「實現化」子系統,從每個實現化子系統繪製一道指向規格子系統的實現化。
基本上,UML 2.0 所適用的相同規格和實現化考慮,這裡也適用(請參閱何時及如何使用、相依性和實作關係,以取得說明)。
其他資訊
請參閱 UML1.x 和 UML 2.0 之間的差異,以取得詳細資訊。
|