| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 跟着 Guava、Spring 学习如何设计观察者模式 -> 正文阅读 |
|
[Java知识库]跟着 Guava、Spring 学习如何设计观察者模式 |
文章首发在公众号(龙台的技术笔记),之后同步到掘金和个人网站:xiaomage.info 今天讲解一篇行为型设计模式,什么是行为型?行为型主要负责设计 类或对象之间的交互。工作中常用的观察者模式就是一种行为型设计模式 最近在尝试重构之前写过的代码。在重新梳理过业务之后,发现已有的设计场景应该能够接入到设计模式,而且查看了代码的提交记录,更是坚定了此想法 保持之前的一贯作风,想要说明一个设计模式,需要三板斧支撑。什么是观察者模式?如何使用观察者模式?项目中应该如何应用?
什么是观察者模式观察者模式 是一种行为设计模式,允许定义一种订阅通知机制,可以在对象(被观察者)事件发生时通知多个 “观察” 该对象的观察者对象,所以也被称为 发布订阅模式 其实我个人而言,不太喜欢使用文字去定义一种设计模式的语义,因为这样总是难以理解。所以就有了下面生活中的例子,来帮助读者更好的去理解模式的语义。类图如下所示: 在举例说明前,先让我们熟悉下观察者模式中的
我们跑一下上面的观察者模式示例,如果不出意外的话会将两个观察者执行逻辑中的日志打印输出。如果是平常业务逻辑,抽象观察者定义的入参是具有业务意义的,大家可以类比项目上使用到的 MQ Message 机制
观察者模式结合业务因为公司业务场景保密,所以下面我们通过【新警察故事】的电影情节,稍微篡改下剧情,模拟出我们的观察者模式应用场景 假设:目前我们有三个警察,分别是 如果说使用常规代码写这套流程,是能够实现需求的,一把梭的逻辑可以实现一切需求。但是,如果说下次行动,龙哥让老三跟着自己实施抓捕,亦或者说龙哥团队扩张,来了老四、老五、老六…
如果按照上面的设想,我们通过“一把梭”的方式把代码写出来会有什么问题呢?如下:
第一种我们可以通过,大函数拆小函数 或者 大类拆分为小类 的方式解决代码负责性问题。但是,开闭原则却不能避免掉,因为随着警员(观察者)的增多及减少,势必会面临频繁改动原函数的情况 当我们面对这种 已知会变动,并且可能会 频繁变动不固定 的代码,就要使用抽象思维来进行设计,进而保持代码的简洁、可维护 这里使用 Java SpringBoot 项目结构来书写观察者模式,代码最终推送到 Github 仓库。读者可以先把仓库拉下来,因为其中不止示例代码,还包括 Guava 和 Spring 的观察者模式实现,GitHub 仓库地址 首先,定义观察者模式中的观察者角色,分别为抽象观察者接口以及三个具体观察者实现类。实际业务中,设计模式会和 Spring 框架相结合,所以示例代码中包含 Spring 相关注解及接口 其次,定义抽象被观察者接口以及具体被观察者实现类。同上,被观察者也需要成为 Spring Bean,托管于 IOC 容器管理 到这里,一个完整的观察者模式就完成了。但是,细心的读者会发现这样的观察者模式会有一个小问题,这里先不说明,继续往下看。接下来就需要实际操练一番,注册这些观察者,通过被观察者触发事件来通知观察者 如何实现开闭原则看了应用的代码之后,函数体过大的问题已经被解决了,我们通过 拆分成为不同的具体的观察者类 来拆分总体逻辑。但是开闭原则问题呢?这就是上面所说的问题所在,我们目前是通过 显示的引入具体观察者模式 来进行添加到被观察者的通知容器中,如果后续添加警察老四、老五… 越来越多的警察时,还是需要改动原有代码,问题应该怎么解决呢 其实非常简单,平常 Web 项目基本都会使用 Spring 框架开发,那自然是要运用其中的特性解决场景问题。我们这里通过 改造具体被观察者实现开闭原则 如果看过之前作者写过的设计模式文章,对
后续如果再有新的观察者类添加,只需要创建新的类实现抽象观察者接口即可完成需求。有时候,能够被封装起来的不止是 DateUtil 类型的工具类,一些设计模式也可以被封装,继而更好的服务开发者灵活运用。这里会分别介绍 同步异步的概念在介绍
这里给大家举个例子,能够很好的反应同步、异步的概念。比如说你想要给体检医院打电话预约体检,你说出自己想要预约的时间后,对面的小姐姐说:“稍等,我查一下时间是否可以”,这个时候如果你 不挂电话,等着小姐姐查完告诉你 之后才挂断电话,那这就是同步。如果她说稍等需要查一下,你告诉她:“我先挂了,查到结果后再打过来”,那这就是异步+回调 在我们上面写的示例代码上,毋庸置疑是通过同步的形式执行观察者模式,那是否可以通过异步的方式执行观察者行为?答案当然是可以。我们可以通过在 观察者模式行为执行前创建一个线程,那自然就是异步的。当然,不太建议你这么做,这样可能会牵扯出更多的问题。一起来看下 Guava 和 Spring 是如何封装观察者模式 Guava EventBus 解析
具体代码已上传 GitHub 代码仓库, 因为
注意一点,创建
大家有兴趣可以去看下 Spring 事件模型如果想要使用
Spring 事件与 Guava EventBus 一样,代码就不粘贴了,都已经存放到 Github 代码仓库。这里重点介绍下 Spring 事件模型的特点,以及使用事项 Spring 事件同样支持异步编程,需要在具体 Listener 实现类上添加 作者建议读者朋友一定要跑下 结言文章通过图文并茂的方式帮助大家梳理了下观察者模式的实现方式,更是推出了进阶版的 最后解答下最早提到的问题,项目中的观察者模式 应该使用同步模型还是异步模型呢 如果只是使用观察者模式拆分代码使其满足 开闭原则、高内聚低耦合、职责单一 等特性,那么自然是使用同步去做,因为这种方式是最为稳妥。而如果 不关心观察者执行结果或者考虑性能 等情况,则可以使用异步的方式,通过回调的方式满足业务返回需求 关于观察者设计模式本文就讲到这里,后面会陆续输出工厂、原型、享元等模式;如果文章对你有帮助那就点个关注支持下吧,祝好。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 16:38:01- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |