java设计模式解析(1) Observer观察者模式
主要内容
2、实现代码(Talk is cheap,Show me the code)
观察者设计模式在日常软件开发非常常见。比如MQ消息监听、ZooKeeper监听节点事件、Spring发布事件以完成容器初始化(后续会有分析)等。
度娘上对观察者模式有很多版本定义,个人觉得还是《设计模式之禅》定义比较全面,不愧设计模式宝典啊。先贴出来具体定义:
针对上面给出的几个关键对角色,补充一下自己的理解:
1)、Subject:被观察者,即事件的起源。一般在软件实现阶段是 接口 或者 抽象类
2)、Observer:观察者,即观察到事件发生则同步更新自身的状态。一般在软件实现阶段是 接口 或者 抽象类
2、实现代码(Talk is cheap,Show me the code)
《设计模式之禅》已经给出具体的代码实现部分,但是个人觉得过于标准化,现实软件落地肯定会对其进行改造,例如Spring发布事件机制(后续会有分析)。这里个人实现场景,欢迎拍砖:
定义:大学每个学期都会提前订阅该学期的课程,一个课程会被N多个学生订阅。假设某个数学课程任课老师变更之后,学生需要同步更新课程信息,实现自级联变更。
分析:此时可以看出来【课程】就是被观察者的角色,【学生】就是观察者的角色。当【课程】有变动即任课老师变更,需要及时通知【学生】。
Subject课程
/** * 课程 被观察的对象 * @author zhou.guangfeng on 2019/8/21 下午5:29 */ public interface Subject { void teacherChange(String teacherName) ; }
Student学生
/** * 学生 观察者 * @author zhou.guangfeng on 2019/8/21 下午5:29 */ public interface Student { void changeSubjectTeacherName(String teacherName) ; }
Observer监听 串联观察者 和 被观察者,同时实现被观察者接口
/** * 监听 串联观察者 和 被观察者。同时实现被观察者接口 * @author zhou.guangfeng on 2019/8/21 下午5:29 */ public class Observer implements Subject { private Subject subject ; private List<Student> studentList = new ArrayList<>() ; public Observer(Subject subject) { this.subject = subject; } @Override public void teacherChange(String teacherName) { subject.teacherChange(teacherName); studentList.forEach(student -> student.changeSubjectTeacherName(teacherName)); } /** * 动态注册观察者 * * @param * @return */ public void registerStudent(Student student){ System.out.println("动态注册观察者 --> " + student); studentList.add(student) ; } /** * 动态删除观察者 * * @param * @return */ public void removeStudent(Student student){ System.out.println("动态删除观察者 --> " + student); studentList.remove(student) ; } }
ObserverMain执行代码
public class ObserverMain { public static void main(String[] args) { // 被观察者 数学课程 Subject shuxue = new Subject() { @Override public void teacherChange(String teacherName) { System.out.println("数学课程 修改老师为 " + teacherName); } }; // 监听者 代理了被观察者 即 数学课程 Observer watcher = new Observer(shuxue) ; Student student = new Student() { @Override public void changeSubjectTeacherName(String teacherName) { System.out.println("学生A 修改老师为 " + teacherName); } } ; // 注册 观察者 watcher.registerStudent(student); watcher.registerStudent(new Student() { @Override public void changeSubjectTeacherName(String teacherName) { System.out.println("学生B 修改老师为 " + teacherName); } }); // 改变课程 watcher.teacherChange("华罗庚"); // 删除监听学生 watcher.removeStudent(student); // 改变课程 watcher.teacherChange("爱因斯坦"); } }
执行结果:
动态注册观察者 --> com.nancy.observer.ObserverMain$2@6f94fa3e 动态注册观察者 --> com.nancy.observer.ObserverMain$3@5e481248 数学课程 修改老师为 华罗庚 学生A 修改老师为 华罗庚 学生B 修改老师为 华罗庚 动态删除观察者 --> com.nancy.observer.ObserverMain$2@6f94fa3e 数学课程 修改老师为 爱因斯坦 学生B 修改老师为 爱因斯坦
(1)、由于触发观察者是顺序调用,如果观察者很多(例子中student群体特别多,触发时间很长)势必会有效率瓶颈,此时可以考虑使用线程池等异步进行。
(2)、关系广播链接不能太复杂,否则将难于维护。
原文地址:https://www.cnblogs.com/xiaoxing/p/11392725.html
- 实现去哪儿来回机票选择的view
- 解决水平ListView在ScrollView中出现的滑动冲突
- Android逆向分析(2) APK的打包与安装背后的故事
- Activity之间传递大数据问题
- React Native入门(二)Atom+Nuclide安装、配置与调试
- React Native入门(一)环境搭建与Hello World
- android 自定义Viewpager实现无限循环
- Android内存优化(二)DVM和ART的GC日志分析
- Android Material Design之Toolbar与Palette实践
- android-async-http框架源码分析
- 使用Buck构建Android工程
- android 实现淘宝收益图的折线
- React Native入门(三)组件的Props(属性)和State(状态)
- Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)【Dalston版】
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- LinkedList - 141. Linked List Cycle
- LinkedList - 206. Reverse Linked List
- Array - 188. Best Time to Buy and Sell Stock IV
- Tree - 112. Path Sum
- 首个无tricks的情况下将ResNet-50提高到80%+!CMU开源MEAL V2
- Tree - 257. Binary Tree Paths
- Tree - 226. Invert Binary Tree
- Tree - 101. Symmetric Tree
- Tree - 100. Same Tree
- Tree - 102. Binary Tree Level Order Traversal
- Dynamic Programming - 91. Decode Ways
- Dynamic Programming - 213. House Robber II
- Dynamic Progamming - 198. House Robber
- Dynamic Programming - 221. Maximal Square
- Dynamic Programming - 174. Dungeon Game