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

 Pattern-Oriented Software Architecture (簡稱:POSA)是除了GoF 的 Design Patterns: Elements of Reusable Object-Oriented Software以外的Design Pattern經典書籍。它是一個系列,現在一共有5本,其中的3本好像都有中文版。

這個讀書筆記是有感於那個Vol1的中文版翻譯太差勁,以至到句子都不通順的地步,看那個中譯本完全不知所云,還不如看原版。因此,雖然我的英語不好,但還是硬着頭皮去啃那英語,邊看就邊寫下了讀書筆記,有直接翻譯的部分,主要是爲了以後看起來方便。
這一部分是從[page 266]Proxy模式的Dynamic一節開始,其中跳過了很多我認爲不是很重要或者是評論的小節,還有的我覺得不好翻的我就直接附上了原文以方便理解,圖就沒有包含了,如果要看圖就自己去看原版吧,我都標有頁碼,很容易就能找見:)
我爭取每天更新一部分。

下面,好戲開始:

[page 266]
下圖顯示了典型的Proxy模式結構的動態場景,注意,實際情況決定了proxy內不同的執行動作,更多的信息可以參見[變體]一節:
    - 在運行時,client請求proxy執行服務。
    - proxy接收到一個服務請求,先作預處理,執行一系列動作,如:查找original的地址,或檢查本地緩存,看請求的信息是否已經被緩存並可直接使用。
    - 如果Proxy需要諮詢origial來完成服務請求,則會將請求用適當的通訊協議和安全的方法轉發給original。
    - original接收請求並完成服務,並把服務結果發回給proxy。
    - Proxy接收到original的返回結果。在將它發送回client之前或之後,proxy也許會執行附加的後期處理,如:緩存結果,調用origial的析構函數或釋放佔用資源上的鎖。

[page 267]
[圖]

[實現]
通過以下步驟可以實現Proxy模式:
    1 鑑別出組件中所有處理訪問控制的職責,將這些職責放入一個proxy組件中。此步驟詳細信息在[變體]一節描述。
    2 如果有可能,則引入一個抽象基類表示proxy和original的公共部分,並使proxy和original從此抽象基類繼承。如果proxy和 original採用相同的接口不可行,則可以採用adapter[GHJV95]模式來做接口適配。通過將proxy適配到original的接口,讓 client保持接口一致的錯覺,並且使adapter和original抽取出一個公共基類成爲可能。
    3 實現proxy的功能。在此步驟結束後檢查第一步驟鑑別出的proxy的角色。
    4 將遷移到Proxy中的職責從original和client中清除。
    5 在proxy中存儲一個關聯到original的handle,這個handle可能是一個指針,引用,地址,標識,socket,端口等等。
    6 將所有original和client之間的直接關係都清除掉,將這些關係都替換成類似的client和proxy之間的關係。



[page 268]
[變體]
下面描述幾種普通proxy的變體。首先我們簡單描述各種變體以及他們最適合的環境:
    - 遠程proxy,網絡地址和IPC(inter-process communication,進程間通訊)協議應該被屏蔽在訪問遠程組件的client之外。
    - 保護proxy,防止對組件未經許可的訪問。
    - 緩存proxy,讓多個本地client能共享遠程組件的結果。
    - 同步proxy,同步對同一個組件的併發訪問。
    - 計數proxy,防止意外地刪除組件,並收集使用情況的統計數據。
    - 虛擬proxy,當加載過程和處理過程代價較大時,用滿足部分需求的組件信息返回給client。
    - 防火牆proxy,保護本地client不受外部干擾。



以下的段落詳細描述了每個變體的特性和實現。

遠 程proxy 封裝並維護了original的物理地址,並實現IPC(inter-process communication)標準同original進行實際通訊。針對每個original,proxy將實例一個original服務所要求的地址空 間。對於複雜的IPC機制,你可以像Forwarder-Receiver模式所描述的一樣,在original組件中引入一個receiver,在 proxy中引入一個forwarder,將所有proxy和original的通訊職責移交給forwarder和receiver,以簡化 proxy。

For reasons of efficiency, we discern remote proxies into three cases:
    - client和original在同一個進程中。
    - client和original在同一臺機器中的不同進程中。
    - client和original在不同機器的不同進程中。

[page 269]
第 一種情況很簡單:不需要proxy與original對話。對於第二、三種情況,我們把遠程地址信息放到proxy中,通常包括:機器ID,端口或進程編 號,對象ID。第二種情況明顯不需要機器ID,如果你要節省機器ID所佔用的幾個字節,那麼第二和第三種情況間的差異將導致proxy的代碼變得複雜。在 開發中除非兩種情況下的IPC不同,迫使我們實現這種差異,否則實現這種差異並不合理。即使那樣,你仍然可以在這三種差異的情況上加上一尋址策略層來簡化 代碼。Abstract original可以屏蔽掉這三種情況,讓client對於這三種情況完全不知情。
In high-performance applications, you often want to determine
whether or not communication is expensive at the application level
before committing to an off-board request. In such cases, a remote
proxy reveals this information.



保 護proxy  proxy通過檢查每個client的訪問權限來防止對original未經許可的訪問。最簡單的實現辦法是使用平臺提供的訪問控制機制。如果可能,給每 個訪問組件的客戶設定它自己的訪問許可。訪問控制列表(ACL-Access control lists)就是廣泛使用的一種實現這種機制的技術。


緩 存proxy  可以通過擴展數據區的方式實現在proxy中臨時緩存結果數據,並設計一種策略來維護和更新緩存。當緩存滿了,有多種策略讓你釋放空間給新的數據,比如: 可以刪除最少使用的緩存數據;或採用'move-to-front'策略,採用一個雙鏈表,客戶從前端訪問數據,將新的數據放在前端,尾部的數據被刪除, 這個策略很容易實現並且效率不錯。

同時需要處理'緩存失效'問題,當original中的數據改變時,需要向已經失效的proxy緩存拷 貝這些改變數據。如果這些數據是很重要的數據,並且在客戶中總是需要最新的數據,那可以在original中的數據有任何改變時都將proxy緩存中所有 的數據標爲失效。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章