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 ...
随机推荐
- Windows常用网络命令(3)
5.Netstat Netstat命令可以帮助网络管理员了解网络的整体使用情况.它可以显示当前正在活动的网络连接的详细信息,例如显示网络连接.路由表和网络接口信息,可以统计目前总共有哪些网络连接正在运 ...
- linux命令kill和kill -9的区别
linux命令kill和kill -9的区别 2018年04月13日 16:53:07 坠入苦海销尘垢 阅读数 2854 转载自https://www.cnblogs.com/liuhouhou/ ...
- hdu 2962 题解
题目 题意 给出一张图,每条道路有限高,给出车子的起点,终点,最高高度,问在保证高度尽可能高的情况下的最短路,如果不存在输出 $ cannot reach destination $ 跟前面 $ ...
- java笔记4—继承
继承: 作用: 提高了代码的复用性. 让类与类之间产生了关系,为多态提供了前提 继承中成员变量的特点: 继承中成员函数的特点: 方法重写: 注意:重写方法必须和被重写的方法具有相同的方法名,参数列表和 ...
- maven 打包错误 Cannot access central in offline mode
出错的场景是这样的,先是在一台联网的linux机器上下载项目需要的包,linux机器上jdk为1.8 springboot1.5.然后将项目代码和.m2目录拷贝到一台windows机器上,window ...
- LeetCode977.Squares of a Sorted Array
题目 977. Squares of a Sorted Array Given an array of integers A sorted in non-decreasing order, retur ...
- net core quartz调度 warp打包 nssm部署到windowsservice
介绍下一款vue.js实现的基于core2.1 quartz.net调度框架,独立部署不依赖数据库,只需要实现不同业务接口,配置调度时间即可 github:https://github.com/cq- ...
- STL之 stack的基础应用
头文件 #include<stack> stack<int> s; stack<char> s;//定义一个名字为s 的存int char的stack 基本指令 ...
- Spring AOP创建Throwdvice实例
1.异常发生的时候,通知某个服务对象做处理 2.实现throwsAdvice接口 接口实现: public interface IHello { public void sayHello(String ...
- 易百教程人工智能python修正-人工智能数据准备-标记数据
我们已经知道,某种格式的数据对于机器学习算法是必需的. 另一个重要的要求是,在将数据作为机器学习算法的输入发送之前,必须正确标记数据. 例如,如果所说的分类,那么数据上会有很多标记. 这些标记以文字, ...