科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道[韩小明]剪贴板中的观察者(Observer)模式

[韩小明]剪贴板中的观察者(Observer)模式

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

最近因为工作需要,使用到了剪贴板的特殊功能。也翻阅了一些网上介绍的资料,发现要实现类似FlashGet那样下载工具中监视剪贴板的实现方式,对我们程序设计有点借鉴的意义。

作者:韩小明 来源:CSDN 2007年10月10日

关键字: 韩小明 剪贴板 观察者 模式

  • 评论
  • 分享微博
  • 分享邮件

最近因为工作需要,使用到了剪贴板的特殊功能。也翻阅了一些网上介绍的资料,发现要实现类似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的味道。



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1766118

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章