準則: 設計套件
設計套件是用來分割設計模型的建構。這個準則說明如何識別和指定設計套件。
關係
相關元素
主要說明

簡介

設計模型的結構可以分成較小的單元,以便更容易瞭解。將設計模型元素分組成套件和子系統之後,再顯示這些分組如何彼此關聯,會比較容易瞭解模型的整體結構。請注意, 設計子系統的模型是會實現一或多個介面的元件;如果需要詳細資訊,請參閱工作成果:設計子系統工作成果準則:設計子系統。另一方面,設計套件只是用來分組而已。

套件內容可見度

包含在套件內的類別可以是公用或私密的。任何其他類別都可以建立公用類別的關聯。但只有套件所包含的類別能夠建立私密類別的關聯。

套件介面由套件的公用類別組成。套件介面(公用類別)會隔離和實作對於其他套件的相依性。在這個方式之下,並列開發便簡化了,因為您可以及早建立介面,且開發人員只需要知道其他套件的介面變更。

套件分割準則

您可以為了許多原因而分割設計模型:

  • 在系統完成之後,您可以利用套件和子系統來作為訂購、配置或交付單元。
  • 由於資源的配置和不同開發小組的能力,專案可能需要在不同場所不同群組之間進行分割。定義好介面的子系統可以利用受控而協調的方式,在小組之間分割工作,使設計和實作能夠以平行方式進行。
  • 子系統可以依照反映使用者類型的方式,用來建立設計模型的結構。許多變更需求都是來自使用者;子系統可以確保特定使用者類型的變更只會影響系統中對應於這個使用者類型的部分。
  • 在某些應用程式中,應該只有少數人能夠存取特定資訊。子系統可讓您依照需要來保守區域的秘密。
  • 如果您在建置支援系統,您可以利用子系統和套件,將類似於被支援系統的結構提供給它。在這個方式之下,您便可以同步維護兩個系統。
  • 子系統用來代表系統所用的現有產品和服務(如 COTS 產品和程式庫),下列各節將說明這一點。

套裝界限類別

當界限類別分配給套件時,適用兩種不同的策略;選擇哪一種策略,取決於系統介面未來是否很可能大幅變更。

  • 如果系統介面很可能被取代,或進行大量變更,介面就應該與設計模型的其他部分分開。當使用者介面變更時,只有這些套件會受到影響。從行導向的介面切換到視窗導向的介面,便是這類主要變更的範例。

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

如果主要目標是簡化主要介面變更,界限類別就應該放在一或多個個別套件中。

  • 如果介面沒有規劃任何主要變更,就應該以系統服務的變更而不是介面變更為領導原則。之後,應該將界限類別與功能相關的實體和控制類別放在一起。在這個方式之下,便很容易看出來,如果特定實體或控制類別有了改變,哪些界限類別會受到影響。

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

為了簡化系統服務的變更,將界限類別與功能相關的類別套裝在一起。

功能與任何實體或控制類別都無關的強制界限類別應該放在個別套件中,與屬於相同介面的界限類別放在一起。

如果界限類別與某個選用的服務相關,請將它與合作提供服務的類別一起放在個別子系統中。這個子系統會對映到訂購選用的功能時將提供的選用元件。

套裝功能相關的類別

每個功能相關的類別群組都應該識別出一個套件。當判斷兩個類別的功能是否相關時,有幾個適用的實際準則。依照重要性遞減順序排列,它們是:

  • 如果一個類別的行為和/或結構變更必然會造成另一類別的變更,這兩個類別的功能便相關。

範例

如果將新屬性加到實體類別訂單 (Order) 中,很可能必須更新控制類別訂單管理者 (Order Administrator)。因此,它們屬於相同的訂單處理套件。

  • 從一個類別開始(如實體類別),檢查從系統中移除它會有什麼影響,便可能得知這個類別是否與其他類別相關。任何因移除其他類別而成為多餘的類別,都會在某個程度上連接到移除的類別。多餘是指只有已移除的類別會使用這個類別,或這個類別相依於已移除的類別。

範例

倉庫系統有一個訂單處理套件,其中包含訂單管理者訂單登記員 (Order Registrar) 這兩個控制類別。這兩個控制類別用來建立關於倉庫訂單處理的服務模型。所有訂單屬性和關係都由專用來處理訂單的訂單實體類別來儲存。如果移除了這個實體類別,就不再需要訂單管理者訂單登記員,因為 訂單必須存在,它們才有用。因此,實體類別訂單應該包括在兩個控制類別的相同套件中。

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

訂單管理者訂單登記員屬於訂單的相同套件,因為從系統中移除訂單之後,它們就是多餘的。

  • 如果兩個物件會與大量訊息互動,或有複雜的交互通訊,這兩個物件的功能便可能相關。

範例

控制類別作業執行者 (Task Performer) 會與運輸者介面 (Transporter Interface) 來回收送許多訊息。這是它們應該併入相同套件作業處理 (Task Handling) 的另一個指示。

  • 如果界限類別的功能是呈現實體類別,界限類別的功能便可能與特定實體類別相關。

範例

倉庫系統中的界限類別集裝架表格 (Pallet Form) 會將實體類別集裝架 (Pallet) 的實例呈現給使用者。每個集裝架都用螢幕中的識別號碼來表示。如果集裝架的相關資訊有了改變,比方說,如果也提供了集裝架的名稱,界限類別也可能需要變更。因此,集裝架表格應該併入 集裝架的相同套件中。

  • 如果兩個類別會與相同參與者互動,或會受到相同參與者的變更影響,這兩個類別的功能便可能相關。如果兩個類別並未涉及相同的參與者,它們就不應放在相同套件中。當然,在某些重要原因之下,您可以忽略最後一個規則。

範例

倉庫系統有一個作業處理套件,它除了其他項目之外,還包含控制類別作業執行者。這是唯一與運輸者 (Transporter) 參與者相關的套件,這位參與者就是能夠在倉庫中運送集裝架的實際運輸者。參與者會與透過界限類別運輸者介面來與控制類別作業執行者互動。因此,這個界限類別應該併入作業處理套件中。

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

運輸者介面作業執行者屬於相同套件,因為它們都會受到運輸者參與者變更的影響。

  • 如果兩個類別彼此相關(關聯、聚集等),這兩個類別的功能便可能相關。當然,這個準則不能盲目遵循,但沒有其他適用的準則時,便可以使用它。
  • 類別的功能可能與建立其實例的類別相關。

下面這兩個準則用來判斷兩個類別應該放在相同套件的情況:

  • 兩個與不同參與者相關的類別不應該放在相同套件中。
  • 選用和強制的類別不應放在相同套件中。

評估套件內聚力

首先,套件中的所有元素必須有相同的選用性:在強制的套件中,不能有選用的模型元素。

範例

強制實體類別 Article Type 有稱為 Restock Threshold 的屬性及其他項目。不過,系統中重新進貨功能是選用的。因此,Article 應該分割成兩個實體類別,其中選用類別會建立強制類別的關聯。

被視為強制的套件不能相依於被視為選用的任何套件。

作為一項規則,兩個不同的參與者不能使用單一套件。原因在於一個參與者的行為變更不應該影響另一個參與者。這個規則有些例外,例如構成選用服務的套件。這類型的套件不應分割,不論有多少參與者使用它都是如此。因此,除非套件是選用的,否則,請分割有多個參與者使用的任何套件或類別。

相同套件中的所有類別,功能必須相關。如果您遵循「從功能相關的類別中尋找套件」一節中的準則,套件中各個類別本身的功能會彼此相關。不過,特定類別本身可能會包含「太多」行為,或不屬於類別的關係。這時應該移動類別的一部分來成為全新的類別,或移到可能屬於另一套件的其他類別中。

範例

在某套件內的 A 控制類別的行為,不應該過度依賴另一套件內的 B 類別。如果要隔離 B 專用的行為,A 控制類別必須分割成 A'A" 兩個控制類別。B 專用的行為放在新控制類別 A" 中,這個類別在 B 的相同套件中。新類別 A" 也會取得與原始物件 A' 的一項關係(如一般化)。

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

如果要隔離 B 專用的行為,欠缺同質性的 A 控制類別會分割成 A'A" 兩個控制類別。

說明套件相依性

如果一個套件中的類別會關聯於不同套件中的類別,這些套件便是彼此相依。套件相依性的模型是利用套件之間的相依性關係來建立。相依性關係可協助我們存取變更結果:與不被任何套件依賴的套件相比,有許多套件依賴的套件比較難變更。

由於在指定套件規格期間,會發現許多這類相依性,因此,在工作期間,這些關係一定會改變。相依性關係的說明可能包括哪些類別關係造成相依性的相關資訊。由於這會引進不容易維護的資訊,因此,只有在資訊相關而有價值時,才應該這麼做。

範例

倉庫系統中,有從訂單處理 (Order Handling) 套件到項目處理 (Item Handling) 套件的相依性關係。產生這個關聯是因為訂單處理中的實體類別訂單 (Order) 有一項對於其他套件之實體類別項目類型 (Item Type) 的關聯。

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

訂單處理套件相依於項目處理,因為套件的兩個類別之間有一項關聯。

評估套件耦合性

套件耦合性既好又不好:好,是因為耦合性代表重複使用,不好,是因為耦合性代表相依性,而相依性會使系統更難改變和發展。以下是您可以遵循的部分一般原則:

  • 套件不應交互耦合(也就是相互相依);例如,兩個套件不應彼此相依。

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

在這些情況下,必須重組套件來移除交互相依性。

  • 下層套件不應依賴上層套件。套件只能依賴同層及下一層套件。

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

在這些情況下,需要重新分割功能。一個解決方案是透過介面來說明相依性,並在下層組織介面。

  • 一般而言,相依性不應略過層次,除非所有層次共用相依行為,替代方法是在層次之間簡單傳遞作業呼叫。
  • 套件不應相依於子系統,只應相依於其他套件或介面。