设计模式——观察者众

前 言
写设计模式的技术大佬很多,布衣博主深感自身技术粗浅,本来不想人从众,但对于知识的理解、应用每个技术人还是有很大的不同的——如果把某种技术抽象来看的话,那么这种技术被不同的技术人员实现出来就会产生千人千种哈姆雷特的纷繁效果 。所谓 纸上得来终觉浅,绝知此事要躬行 。别人理解的终究是别人的,你看懂了不一定会运用,自己如何内化吸收,学以致用才是关键 。因此,基于对技()术(bi)的热(ke)爱(wang),博主有时间,还是会讲点设计模式方面的知识 。不过设计模式毕竟是思想层面的东西,怎么运用才是关键,所以博主会重点着笔于设计模式的现实运用 ,而不只是干巴巴的概念化讲述 。写的不一定好,但保证一定很用心 。
模式理解
观察者模式,如果要好理解的话,应该称其为 发布——订阅模式 。联想一下以前报纸横行的时代的订阅报纸以及如今微信时代的订阅公众号等现实场景,从对象关系模型的角度来分析,这两种场景都会涉及两大主体对象:消息的订阅者和消息的发布者 。产生的实际效果就是,你订阅了报纸,那么报纸发行的时候自然少不了你的一份;你订阅了某公众号,那么公众号有新动态的时候也会实时的推送到你面前 。可以看出,发布者和订阅者之间的关系,是一种很明显的一对多关系 。不过,在正式的设计模式称谓中,我们称消息发布者为主题(【s?bd??kt】),称消息订阅者为观察者(【?b'z??v?】),故博主才曰观察者众 。至此,从理解层面上来说,如果你不是傻子的话,对于观察者模式,你肯定已经知其然了 。
模型分析
就像很多道理知易行难一样,虽然观察者模式比较好理解,但是要怎么将其设计成能够开发运用的对象关系模型,还是要费一番思量 。这里,博主先不直接上UML类图,度娘一下就有,先按照上面的理解,来设计草稿 。从模式理解可以分析出,消息的订阅者至少需要两个基本功能:订阅和取消订阅,而消息发布者的功能就是发布消息,但是发布消息应该是一种广播的方式,要将更新的消息发布给所有的订阅者对象,所以,其内部应该维护一个存储所有对象引用的集合 。按照这样简单的理解话,草图大概就是博主如下丑画的模样:

设计模式——观察者众

文章插图
自我感觉画的很到位,真正的在设计类图的时候,按照上图去设计,是有一定问题的 。从语言描述上,订阅者根据需要订阅或取消订阅,似乎订阅和取订是订阅者自己的功能,但仔细分析则不然,应该是消息的发布者【主题】暴露给消息订阅者【观察者】的功能项 。因为消息的发布者内部需要维护一个装有所有订阅者的集合,实际上就是将对集合操作(添加或删除订阅者)的API暴露给了订阅者,而这也是观察者模式中 主题 对象中注册和撤销注册的本质;而至于消息发布者如何将消息发布给消息的订阅者呢?不用想复杂了,就是一个简单的发布者对订阅者方法的调用而已,只不过,发布者要通知所有订阅者的话必须要遍历集合挨个的调用订阅者的消息接收方法 。在设计模式中,我们是要面向接口去设计编程模型的,于是将发布者的注册、撤销注册和订阅者的消息接收等功能都抽象成了抽象方法,将发布者和订阅者也抽象成了主题接口和观察者接口 。到此,基本上,UML类图你就可以画了,下图为百度词条上的UML类图:
设计模式——观察者众

文章插图
需要说明的是,观察者模式只是一种设计思想,你只要搞清楚主题【】和观察者【】之间的关联关系就够了,至于具体的抽象接口如何去设计,是要根据自己的业务需求进行灵活变动的,还可添加自己业务相关的其它功能项,以上UML图可以参考,但千万不能硬套,否则就会囿于模式,裹足难行 。