Pattern-Oriented Software Architecture v1巨詳細讀書筆記 2

POSA vol.1 [page 276--281]

------------------------------------------------

[270] 

……
(--跳過了部分proxy變體,例子和已知應用--)




[276]
3.5管理
一個系統通常處理一組類似的對象、服務,甚至複雜的組件。從用戶或者其他系統輸入的事件需要解析並安排好,這就是個例子。另外一個例子是,交互系統需要將特定應用程序的數據通過不同方式呈現出來,這些視圖獨立或整體地都能得到適當處理。

在結構良好的系統中,通常需要獨立的‘manager’組件處理類似的一組對象,在這裏描述兩種此類設計模式:
    - Command Processor 將一個服務的請求與執行分離,一個Command Processor組件把請求作爲獨立的對象來管理,安排它的執行,並提供附加的服務,比如:將請求對象存儲起來供撤銷時使用。

    - View Handler 幫助軟件系統管理視圖,允許客戶打開、操作、排列視圖,協調相互依賴的視圖,並組織他們更新。

Command Processor 模式和Command模式[GHJV95]都採用將服務請求封裝進一個命令對象的概念,然而,Command Processor把Command模式嵌入進了管理命令對象的結構中。在[GHJV95]中也描述了另外了的管理模式,Memento:
    - Memento 允許你在不破壞封裝性的前提下使一個對象的的內部狀態能被捕獲,並存儲下來。
Memento幫助你管理特定組件的狀態,例如:在撤銷已經執行的操作時需要恢復組件狀態,或者客戶端需要在不破壞封裝性的前提下訪問組件的狀態。Memento提供給客戶端拷貝當前狀態的功能。


[277]
[Command Processor]
Command Processor 設計模式 將一個服務的請求與執行分離,一個Command Processor組件把請求作爲獨立的對象來管理,安排它的執行,並提供附加的服務,比如:將請求對象存儲起來供撤銷時使用。

[例子]
文本編輯器通常允許用戶修正自己的失誤,比如:撤銷最近作的修改,甚至允許撤銷很多步的修改。我們要開發這樣的一個編輯器,讓我們叫他TEDDI。
TEDDI的設計中包括了多步撤銷的機制,並允許在以後增強功能,比如:添加新的特性,或者允許批量的操作。
TEDDI的界面提供了多種交互方式,比如:鍵盤輸入或者彈出菜單。在程序中要定義一個或多個回調過程,這些回調過程將會在人機交互時自動被調用。



[278]
[問題]
An application that includes a large set of features benefits from a
well-structured solution for mapping its interface to its internal
functionality. This allows you to support different modes of user
interaction, such as pop-up menus for novices, keyboard shortcuts
for more experienced users, or external control of the application via
a scripting language.
爲了執行用戶請求,你經常需要在系統中實現一些核心功能以外的服務,如:撤銷,重做,批量宏,活動日誌,請求的調度和暫停。
The following forces shape the solution:
    - 不同的用戶喜歡用不同的方式使用應用程序
    - 增強已有的應用程序不應該破壞已有的代碼
    - 如撤銷這樣的附加服務應該‎對所有的請求都實現成一致的。

[解決方案]
Command Processor模式基於Command模式[GHJV95],兩種模式都採用了將請求封裝進對象的概念,當用戶調用應用程序的特定功能時,請求都被轉 變成一個command對象,Command Processor模式更明確地闡明瞭command對象是怎麼被管理的。在[參見]一節將會討論兩種模式的不同。

Command Processor 是此模式的中心組件,它會照料所有的command對象,會調度command的執行,也許會存儲這些command命令用以撤銷操作,也可能會爲了測試 的目的在日誌中記錄command的運行序列。每個command對象都將它任務的執行代理給在應用程序功能核心中的supplier組件。

[結構]
Abstract command 組件定義了所有command對象的接口,最少包含了一個執行此命令的方法,若需要享受command processor提供的附加服務,則需要此接口給所有的command對象定義更多的方法,如:TEDDI中的abstract command類就定義了一個附加的undo方法。
[279]
對於每個用戶功能我們都從abstract command繼承一個command組件,並實現接口中的方法,在這個command組件中會用到多個(0..n)個supplier組件。TEDDI 的command組件會在執行之前保存相關的supplier組件狀態,在撤銷的時候會恢復這些狀態,例如,刪除命令將負責存儲刪除掉的文本和其在整個文 檔中的位置。
[圖]
Controller表示應用程序的界面,它接收如‘粘貼文本’這樣的請求,並創建相應的command對象,把此command交付給command processor去執行。TEDDI的controller維護事件循環,並映射輸入事件爲一個command對象。
Command Processor 管理command對象,調度並執行他們,它是實現執行command的附加服務的關鍵組件,它能保持獨立於特定的command的原因在於它只使用 abstract command接口。在TEDDI中,command processor也存儲已經執行的command用於撤銷功能。
Supplier 組件提供大部分執行具體command的功能(具體command是相對於abstract command而言的),有關聯的command通常共享supplier組件。當需要撤銷機制時,supplier通常提供保存和恢復內部狀態的方法。 TEDDI中主要的supplier組件實現的是內部文本的表示。

[280]
[圖]
下圖顯示了本模式中組件間的主要關係,並用“撤銷“作爲一個command processor提供的附加服務的例子。
[圖]

[281]
[動態]
下圖顯示了實現“撤銷”機制的command processor的典型場景。一個將選定的單詞變成大寫的請求到達,被執行,然後又被撤銷,將會出現以下步驟:
    - controller從事件循環中接收用戶輸入的請求,並創建一個名爲‘capitalize’的command對象。
    - controller將新生成的對象傳給command processor進一步處理。
    - command processor激活command的執行,並把command存儲起來以備撤銷。
    - 名爲‘capitalize’的command對象從它的supplier中獲得當前選擇的文本,將文本以及文本所在文檔中的位置保存下來,並請求supplier將選定的文本變成大寫。
    - 接收到‘撤銷’操作後,controller將此請求傳給command processor,它會執行最近執行的command的撤銷操作。
    - 名爲‘capitalize’的command對象將設置supplier的狀態爲之前的狀態,這將通過在原始位置把文本替換成保存下來的原始文本來實現。
    - 如果在此command對象上沒有更多的動作請求可能,則從command processor中刪除此command對象。
[圖]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章