java设计模式解析(1) Observer观察者模式
设计模式系列文章 |
java设计模式解析(1) Observer观察者模式 |
主要内容 |
2、实现代码(Talk is cheap,Show me the code)
1、简述
观察者设计模式在日常软件开发非常常见。比如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 修改老师为 爱因斯坦
3、注意点
(1)、由于触发观察者是顺序调用,如果观察者很多(例子中student群体特别多,触发时间很长)势必会有效率瓶颈,此时可以考虑使用线程池等异步进行。
(2)、关系广播链接不能太复杂,否则将难于维护。
java设计模式解析(1) Observer观察者模式的更多相关文章
- java设计模式解析(11) Chain责任链模式
设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析(4) ...
- Java设计模式(20)观察者模式(Observer模式)
Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循 ...
- java设计模式(六)--观察者模式
转载:设计模式(中文-文字版) 目录: 简单目标任务实现 观察者模式介绍 观察者模式代码实现 观察者模式是JDK中使用最多的模式之一,非常有用.我们也会一并介绍一对多关系,以及松耦合(对,没错,我们说 ...
- 设计模式18:Observer 观察者模式(行为型模式)
Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...
- Java设计模式学习笔记(观察者模式)
观察者模式说起来很简单,就是一个订报纸的模式.但是实际上这部分我觉得还是很有意思的,<Head First设计模式>里还有一些还没看完,也是因为理解的不够深吧. 观察者模式会包含两个组件: ...
- Java设计模式模式观测(Observer Pattern)
Observer Pattern 设计模式通常用于.这是一个事件侦听器模型. 该模型有两个作用,一个是Subject, 有一个Observer.Subject 保存多个Observer参考,一旦一个特 ...
- 【设计模式】java设计模式总述及观察者模式
今天在准备腾讯的面试时想起来要复习一下设计模式,而刚好前几天在参加网易的在线考试的时候,也出了一道关于设计模式的选择题,主要是考察观察者模式,虽然那道题自己做对了,但觉得还是应该好好总结一下设计模式的 ...
- Java设计模式(三)——观察者模式和监听器
为了实现多个模块之间的联动,最好的方法是使用观察者模式.网上介绍的资料也比较多,今天我就从另一个方面谈谈自己对观察者模式的理解.从JDK提供的支持库里,我们能够找到四个对象:Observable.Ob ...
- Java设计模式(二) 观察者模式
观察者模式: 定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会受到通知并自动更新. 1,定义事件源接口 package com.pattern.observer; pub ...
随机推荐
- Appium元素定位难点:混合式的native+webview
现在大部分app都是混合式的native+webview,对应native上的元素通过uiautomatorviewer很容易定位到,webview上的元素就无法识别了. 1.认识识webview & ...
- 1、Ant和分布式介绍
{ 1.Maven 简介 2.配置Maven运行环境 3.Maven项目 4.Ant和Maven项目的简单对比 5.Maven项目之间的关系 6.War类型项目的创建(tomcat插件和资源拷贝插件) ...
- IDEA 自定义代码模板
IDEA 自定义代码模板操作步骤:
- FineUI window弹层设置
需在页面先设置 <f:Window ID="Window1" runat="server" Height="600px" Widt ...
- wmi的作用
WMI是Windows 2K/XP管理系统的核心,对于其他的Win32操作系统,WMI是一个有用的插件. WMI的作用是: ①通过它可以访问.配置.管理和监视几乎所有的Windows资源,比如用户可以 ...
- 继承 多态 封装 Python面向对象的三大特性
1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 那这个也可以被称为封装. 2. 继承: 两个 ...
- day27——面向对象的总结、异常处理
day27 面向对象的总结 异常处理 错误的分类 语法错误 if if 2>1 print(222) dic = {"name"; "alex"} 逻辑错 ...
- 深度学习 Bottleneck layer / Bottleneck feature
最近在学习deeplearning的时候接触到了bottle-neck layer,好奇它的作用于是便扒了一些论文(论文链接放在文末吧),系统的了解一下bottle-neck feature究竟有什么 ...
- CMake配置VTK时Qt5_DIR-NOTFOUND的解决方法
直接给解决方法了,不废话. Qt5的路径,请参考:C:\Program\IDE\Qt\Qt5.13.0\5.13.0\msvc2017_64\lib\cmake\Qt5 参考文章 CMake配置VTK ...
- python3基础之“小练习(1)”
(一)打印3个不同的字符 # a=int("123") # b="123" # c=1.2 # print(type(a),a) # print(type(b) ...