剪貼簿中的觀察者(Observer)模式

來源:互聯網
上載者:User

最近因為工作需要,使用到了剪貼簿的特殊功能。也翻閱了一些網上介紹的資料,發現要實作類別似FlashGet那樣下載工具中監視剪貼簿的實現方式,對我們程式設計有點借鑒的意義。

在Windows提供的剪貼簿API中,針對監視這塊,提供的是註冊機制。主要函數是SetClipboardViewer這個API函數。這個函數的聲明是這樣的(Delphi):

function SetClipboardViewer(hWndNewViewer: HWND): HWND; stdcall;

通過這個函數,將一個視窗控制代碼,註冊到系統剪貼簿中。可以稱註冊後的表單為一個Clipboard Viewer,眾多的Viewer形成一個Clipboard Viewer Chain。這個Chain是一個典型的鏈表,前一個記住下一個的指標。

註冊為Viewer的Handle所在的表單,通過處理WM_CHANGECBCHAIN和WM_DRAWCLIPBOARD兩個訊息,來處理所有來自剪貼簿的變化。處理這些訊息的時候,記住向下一個Viewer傳遞訊息,代碼類似於

SendMessage(hwndNextViewer, message, wParam, lParam);

我重點並不是要說明代碼如何編寫,只是簡單地介紹了這個“監控”的實現方式。我們很容易聯想到,這和設計模式中提到的Observer模式是非常類似的。最大的不同點在於,剪貼簿直接使用了訊息系統作為解耦的方式。

正因為有這個相似的地方,我才願意仔細分析一下這種實現方式的優點和缺點。

先來說說優點:

  1. 目標和觀察者之間完全解耦,不需要定義特定介面。
  2. 觀察者可以在任意Window上附加實現。這在很多表單應用的程式來說非常方便。
  3. 可以很方便地實現跨進程、線程的觀察者。這得益於標準的訊息機制。
  4. 跨語言實現沒有什麼問題。
  5. 使用PostMessage和SendMessage可以實現兩種完全不同的更新方式。Subject可以選擇等待和不等待Observer更新完成。

看了這些有點,最重要也是最核心的,就是解耦。再來分析一下缺點:

  1. 編程的過程,必須做到約定編程。約定編程和契約編程最大的差異在於沒有編譯機制。
  2. 在觀察者中可以方便地改變後續觀察者的行為,也可能完全破壞其他的正常功能。據說NetAnts曾經在這方面就有過BUG,導致其他程式無法粘貼資料。
  3. 一般我們的應用情境中,除了M-V(模型-視圖)的模式,還有M-M(模型-模型)的方式,針對第二種方式,這種實現方式不是很適合。
  4. 沒有訊息系統的程式中,不適合使用。比如控制台程式。
  5. 對回應時間要求很高的系統,不適合。因為訊息的回應時間不可控制。

分析完上面的這些有點和缺點,我其實更傾向於從這類設計中吸取Message這個設計項目。巧妙地使用Message,可以有意想不到的效果。

總結一下,設計模式的基本原則之一就是解耦,而Message的特性之一就是解耦。這也就是為什麼我們會發現剪貼簿的監視方式和我們學習的Observer模式很想像的根本。所以說他是模式一點也不為過。只不過少了點OO的味道。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.