Frank Buschmann

Applying Patterns
 

上一頁 下一頁


First Integrate Then Implement(先整合再實作)

Context:我們正使用一次一個樣式的樣式,來定義軟體架構的某特定部分

Problem:

一個給定的樣式,要如何地以最佳化的方式來實作,有兩個壓力必須考慮:

  1. 必須可以依據手邊設計問題的需求,以及整體系統的需求,對實作加以修剪以符合實際需要。

  2. 在還未與現有的軟體架構整合前,就先詳細地定義樣式的細節,很可能會產生不適當的樣式實作。你可能會建立一個漂亮的設計模型,它本身看起來很完美也很漂亮,但它卻無法適用於正在開發的應用程式中。

Solution:

 

在實作樣式的細節前,要先整合此樣式到現有的架構中。首先,先界定樣式的使用端,如果使用端提供了某些部分與樣式所引入的角色相同時,則應用結合類似的責任樣式合併。除此以外,依據其使用端的需求,去定義每一個樣式的元件。例如包括輸出輸入參數、函數名稱、資料結構及演算法。接著依據規格實作每一個樣式的元件。

如果樣式的某些部份-包含其中的元件或元件間的關係-太過於複雜,以致於難以很直覺地去實作;則必須加以進一步地細緻化。依據逐個成長的程序,適當的展開其細節。

至於樣式中可以直接實作的部分,則不要再進一步地拆解;甚至你知道樣式可以在此有所幫助;因為哪只會使的樣式的實作變的複雜。愈多的元件被拆解成次元件,就愈會使得系統難以瞭解、實作及維護。此外,過細的解構也會因為增加元件間過多的溝通而導致系統效能的降低。

Example:

考慮以 Command Processor 樣式[BMRSS96]細緻化 Model-View-Controller [BMRSS96] 架構中 controllers model 間的溝通。

依據 Command Processor 樣式的實作,我們需要定義某 Controller 元件,用以接收使用端的輸入,建立所謂的 command 元件,並將此 command 元件傳送到 command processor 中來執行。不管如何;當我們在實作 Command Processor 樣式時,我們不要定義一個全新的 Controller。相對的,我們把先前在應用 Model-View-Controller 時,所定義的 Controls 加以擴充,將前述的兩個責任加到已定義的 Controller 中。

在此,樣式引入了新的元件 Command Processor Command。但它們的規格仍是由一般性的系統需求所控制。舉例來說,當要求提供 undo/redo 以及 logging 服務時,我們就必須針對此需求來為 Command 元件及 Command Processor元件定義適當的介面。


在將 Command Processor 樣式與現有的設計整合以後,我們就可以接著實作它的細節。有許多樣式可以在此發揮作用。Command 樣式 [GHJV95] 說明如何將使用端的請求封裝成物件,Composite 樣式 [GHJV95] 可以用於提供巨集指令。Singleton 樣式 [GHJV95] 可以確保 Command Processor 只會產生一個物件實例。參與樣式間的關連,可以直接實作而無須再細緻化。例如使用指標或參考。

這裡有一個例子可以說明,如何處理一個樣式的細節並直接實作它。就是以 Observer 樣式來細緻化 Model-View-Controller 結構中 Model-View 的關係。在此關係中,Model 扮演 subject 的角色,而 views 則扮演 observers 的角色。這個結構的實際實作必須要能夠有效率的控制多個 views。為了要維護多個 views,我們在 Model 上增加一個 Registry 元件。為了要通知所有的 view 有關 Model 改變的事實,我們可以應用 Iterator樣式[GHJV95]:一個 Iterator 會巡迴所有已登錄的 view 並呼叫其 update 的方法。

基於強固(robustness)的理由,每當有 view 從 model 的 view registry 中取消訂閱時,我們都必須通知 iterator。否則 iterator 很可能會嘗試去通知一個已不存在的 view。若要解決這個問題,我們可以再次應用 Observer 樣式[GHJV95]:view registry 扮演 subject 而 iterator 則扮演 observer。然而,這次我們可以直接實作此樣式。要通知已登錄的 view 有關 model 的改變,只需要一個 iterator 即可。我們並不需要將 view registry 修改成可處理多個 iterator。因此,我們可在 view registry 中,直接參考一個已事先定義好了的唯一的 iterator,並在 view 登錄或反登錄 model 時,通知此 iterator。就如同在第一個 Observer 應用程式中一樣,在此,我們無須再次應用 Iterator 樣式。


上一頁 下一頁