Frank Buschmann

Applying Patterns
 

上一頁 下一頁


Merge Similar Responsibilities(結合類似的責任)

Context:我們正以先整合再實作的方式去處理某個特定的樣式。

Problem:

我們如何以最佳的方式,將一個樣式整合到現已部分存在的軟體架構中呢。五個壓力必須考慮。

  1. 我們整合此樣式的方式,必須使得現存的架構可以控制它的實作。

  2. 現有架構的元件,可能已經提供了某些定義在此樣式中的責任。

  3. 現有的設計元件或可補充或完備樣式參與者的責任。

  4. 加入新的元件或關連到設計中,可能會增加系統結構的複雜性。

  5. 過度地指派太多不同的責任到一個設計元件中,可能會破壞分別考量的準則。所得到的架構會變的難以瞭解、改變及擴充。


 

Solution:

盡可能地將樣式參與者的責任指派給現有軟體架構的元件;只要它可行並可簡化系統的結構及複雜性。

假如,我們要把結構中某個設計元件整合進某樣式於中時,這使得它必須或應該扮演此樣式中某個特定的參與角色時;會有三種可能的狀況:

  1. 這個設計元件提供了該樣式參與者的所有責任。在這種情況下,我們應直接使用此元件,否則我們會實作同樣的責任兩次。

  2. 這個設計元件提供了該樣式參與者的部分責任。在這種狀況下,我們應擴充並完備此設計元件的缺漏部分後直接使用此元件,否則我們會將原本應該放在一起的構面給分隔開來。

  3. 此設計元件並不提供該樣式參與者的任何責任。在這種情況下,把責任指派到這個設計元件上。不要任意加入新的元件或關連,否則會增加系統結構的複雜性。

如果樣式參與者的責任與現有的設計元件彼此互補,那麼,這對將樣式參與者的責任附加到設計元件上可能是很有用的,不過這端視系統的具體內容而定。

從一方面來說;結合相似的角色,可以避免高度聚合元件間的通訊負擔-而這常會造成效能上的損失。例如,當我們將某個介面從 Bridge 樣式[GHJV95]可能的實作中分離出來時;若能將授權服務也附加到此介面上,將是非常有用的,就如同 Protection Proxy 樣式[BMRSS96] 中所定義的。但是,從另一方面來說;過度地讓一個元件負荷過多不同的責任,很可能會導致效率的缺乏。如果該元件在不同的背景下,分別扮演許多截然不同的角色時,它可能會變成效能的瓶頸。將這些不同的責任區隔開來是比較有效率的。

一般而言,將樣式參與者的責任指派到現有設計元件上,可以幫助降低軟體架構的結構複雜度。同時,也確保樣式的實作是符合系統的需求的,而且反之則否。

無論如何;不要將樣式參與者的責任指派到一個無須提供此責任或必須另外實作此責任的現有設計元件上。依據樣式的實作指引;將其具體化成元件或其間的關係並且整合它們到現有軟體架構,否則我們將會破壞分別考量的準則。

 

Example:


 

假設,我們想要應用 Command 樣式 [GHJV95] 來把對服務的請求封裝成物件,同時又想要擴充它以支援巨集指令。這可以利用 Composite 樣式 [GHJV95] 來幫助解決這個問題。以下將示範如何進一步地精練我們的設計。

在 Command 樣式中 command 元件的責任與在 Composite 樣式中 component 元件彼此互補。使用端並不需要區分巨集指令與單一指令間的差別:都只是執行一個指令。因此,我們將 component 元件的責任附加到 command 元件中。在 Command 樣式中實際的 command 元件已經提供了 Composite 樣式中 leaf 的角色,在此我們不需要再做任何事了。

在我們的設計內容中,Composite 樣式的 composite 元件扮演了巨集指令的角色。然而,巨集指令的責任必須與單一指令的責任區隔開來,否則我們將失去在組合巨集指令時的彈性。因此,我們實作一個分開的巨集指令元件並依據 Composite 樣式的指引整合到設計中。


上一頁 下一頁