Guava、Spring 如何抽象观察者模式?(二)
观察者模式结合业务
因为公司业务场景保密,所以下面我们通过【新警察故事】的电影情节,稍微篡改下剧情,模拟出我们的观察者模式应用场景
假设:目前我们有三个警察,分别是龙哥、锋哥、老三,他们受命跟进犯罪嫌疑人阿祖。如果发现犯罪嫌疑人阿祖有动静,龙哥、峰哥负责实施抓捕行动,老三向警察局摇人,流程图如下:
如果说使用常规代码写这套流程,是能够实现需求的,一把梭的逻辑可以实现一切需求。但是,如果说下次行动,龙哥让老三跟着自己实施抓捕,亦或者说龙哥团队扩张,来了老四、老五、老六...
对比观察者模式角色定义,老四、老五、老六都是具体的观察者(Concrete Observer)
如果按照上面的设想,我们通过“一把梭”的方式把代码写出来会有什么问题呢?如下:
- 首当其冲,增加了代码的复杂性。实现类或者说这个方法函数奇大无比,因为随着警员的扩张,代码块会越来越大
- 违背了开闭原则,因为会频繁改动不同警员的任务。每个警员的任务不是一成不变的,举个例子来说这次针对疑犯,让峰哥实施的抓捕行动,下次就可能是疏散民众,难道每次的更改都需要改动“一把梭”的代码
第一种我们可以通过,大函数拆小函数 或者 大类拆分为小类 的方式解决代码负责性问题。但是,开闭原则却不能避免掉,因为随着警员(观察者)的增多及减少,势必会面临频繁改动原函数的情况
当我们面对这种 已知会变动,并且可能会 频繁变动不固定 的代码,就要使用抽象思维来进行设计,进而保持代码的简洁、可维护
这里使用 Java SpringBoot 项目结构来书写观察者模式,代码最终推送到 Github 仓库。读者可以先把仓库拉下来,因为其中不止示例代码,还包括 Guava 和 Spring 的观察者模式实现 GitHub 仓库地址
首先,定义观察者模式中的观察者角色,分别为抽象观察者接口以及三个具体观察者实现类。实际业务中,设计模式会和 Spring 框架相结合,所以示例代码中包含 Spring 相关注解及接口
其次,定义抽象被观察者接口以及具体被观察者实现类。同上,被观察者也需要成为 Spring Bean,托管于 IOC 容器管理
到这里,一个完整的观察者模式就完成了。但是,细心的读者会发现这样的观察者模式会有一个小问题,这里先不说明,继续往下看。接下来就需要实际操练一番,注册这些观察者,通过被观察者触发事件来通知观察者
文章转自公众号:龙台的技术笔记