Android设计模式—观察者模式
装载请标明出处:https://www.cnblogs.com/tangZH/p/11175120.html
更多精彩文章: http://77blogs.com/?p=279
观察者模式
说白了,就是一个对发生改变,所有依赖于它的对象也发生改变,这是一对多的关系。
比如对象A,对象B,对象C。B与C依赖于A,那么A发生改变,B与C也将发生改变。此时A是被观察者,B与C是观察者。
观察者模式又被称作发布/订阅模式,主要是为了让观察者与被观察者之间进行解耦。
UML图:

角色说明:
Subject(抽象主题):被观察者的一个抽象类,它会把所有观察者的引用保存在一个集合里。抽象主题提供一个接口,可以增加和删除观察者对象。
ConcreteSubject(具体主题):具体的被观察者。当具体被观察者的状态发生改变的时候,会给每一个注册过的观察者发送通知。
Observer(抽象观察者):所有具体观察者的一个抽象类,为所有的具体观察者定义了一个接口:得到主题的通知时候更新自己。
ConcrereObserver(具体观察者):抽象观察者的具体实现。
我们看一下具体的例子:
上课铃声响起时候,老师与学生们的不同反应。
1、定义一个抽象主题:
该抽象主题定义了一些通用的方法,即具体主题里面需要实现的。
//抽象被观察者
public interface Observable {
//添加观察者
void addObserver(Observer observer); //移除观察者
void deleteObserver(Observer observer); //通知观察者
void notifyObserver(String msg);
}
2、创建一个具体主题(上课铃声):
public class AlarmClock implements Observable {
//保存观察者对象
List<Observer> list = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
list.add(observer);
}
@Override
public void deleteObserver(Observer observer) {
list.remove(observer);
}
/**
* 通知观察者
* @param msg
*/
@Override
public void notifyObserver(String msg) {
for (Observer observer : list) {
observer.action(msg);
}
}
}
3、创建抽象观察者:
定义了所有具体观察者需要实现的方法,听到铃声后的行为
//抽象观察者
public interface Observer {
void action(String msg);
}
4、创建具体观察者:
public class Students implements Observer {
String name;
public Students(String name) {
this.name = name;
}
@Override
public void action(String msg) {
System.out.println(msg + name + "开始听课");
}
}
public class Teacher implements Observer {
@Override
public void action(String msg) {
System.out.print(msg + "老师开始讲课");
}
}
6、实现:
Observable alarmClock = new AlarmClock();
Observer student1 = new Students("小屁孩");
Observer student2 = new Students("大屁孩");
Observer teacher = new Teacher();
//注册观察者
alarmClock.addObserver(student1);
alarmClock.addObserver(student2);
alarmClock.addObserver(teacher);
//被观察者通知已经注册的观察者
alarmClock.notifyObserver("上课铃声已经响了");
7、结果:

到这里我们便实现了观察者模式。
应用场景
- 当一个对象的改变需要通知其它对象改变时,而且它不知道具体有多少个对象有待改变时。
- 当一个对象必须通知其它对象,而它又不能假定其它对象是谁
- 跨系统的消息交换场景,如消息队列、事件总线的处理机制。
优点
- 解除观察者与主题之间的耦合。让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。
- 易于扩展,对同一主题新增观察者时无需修改原有代码。
缺点
- 依赖关系并未完全解除,抽象主题仍然依赖抽象观察者。
- 使用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。
- 可能会引起多余的数据通知。
JDK内部也内置了Observable(抽象被观察者),Observer(抽象观察者)这两个类,我们也可以直接拿来用,具体可以去看看源码。
- 点击事件
- listView的刷新
- 广播等等
Android设计模式—观察者模式的更多相关文章
- Android设计模式-观察者模式
原文地址 http://blog.csdn.net/qq_25806863/article/details/69218968 观察者模式是一种使用频率非常高的设计模式,最常用的地方就是订阅-发布系统. ...
- Android设计模式---观察者模式小demo(一)
1,今天刚好看到了设计模式这一块来,而观察者模式是我一直想总结的,先来看看观察者模式的简单的定义吧 "当一个对象改变时,他的所有依赖者都会受到通知,并自动更新." 一般我们项目中就 ...
- Android设计模式—— 观察者模式(以及EventBus的简单使用)
1.概述 观察者模式最常用的地方是GUI系统.订阅-发布系统.观察者模式的一个重要作用就是解耦,将观察者和被观察者解耦,使得他们之间的依赖性更小. 2.定义 定义对象间的一种一对多依赖关系,使得每当一 ...
- Android设计模式系列
http://www.cnblogs.com/qianxudetianxia/category/312863.html Android设计模式系列(12)--SDK源码之生成器模式(建造者模式) 摘要 ...
- 经常使用的android设计模式
一般来说,经常使用的android设计模式有下面8种:单例.工厂.观察者.代理.命令.适配器.合成.訪问者. 单例模式:目的是为了让系统中仅仅有一个调用对象,缺点是单例使其它程序过分依赖它,并且不 ...
- 18. 星际争霸之php设计模式--观察者模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- Android中观察者模式的升入理解
以前对Java中的观察者模式只知道一点皮毛,在接触Android的过程中,逐渐认识到观察者模式是如此的重要,android中许多地方都用到了观察者模式例如ContentResolver操作,来总结一下 ...
- Android设计模式(五岁以下儿童)--简单工厂模式
1.面试的时候问这个问题: 在ListView 的item小程序.很多不同的显示风格.或者是,为了更好地维护,不同的样式,应该怎么做? 我一下就想到的是工厂的模式,利用project,编写ViewFa ...
- linkin大话设计模式--观察者模式
linkin大话设计模式--观察者模式 观察者模式定义了对象间的一对多依赖关系,让一个或者多个观察者观察一个对象主题.当主题对象的状态发生改变的时候,系统能通知所有的依赖于此对象的观察者对象,从而能自 ...
随机推荐
- 第9场 E-All men are brothers(并查集)
题目链接 题意:n个人,m次操作,每次操作使得两个人(x,y)成为朋友,朋友的关系是可以传递的,计算执行每次操作后,选择四个人两两都不是朋友的不同方案的数目. 数据范围:(n <= 100000 ...
- MySQL将一个表的查询结果作为本表的查询条件更新数据
先建一张S01人口统计信息表: drop table if exists S01人口统计信息; /*================================================== ...
- linux下信号量可设值的函数操作
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <errno.h ...
- 行内元素(inline标签)设置了行高为什么不生效,还是表现为父盒子的行高?行内元素行高问题终极解释
最近在看张鑫旭大佬的<css世界>,读到5.2.4 内联元素 line-height 的“大值特性” ,产生了疑惑, 在开发中确实也遇到了同样的问题,深入探究后得出结果,先说结论吧,论证 ...
- VS #region
1.C# 预处理指令 #region使您得以在使用Visual Studio代码编辑器的大纲显示功能时指定可展开或折叠的代码块. #region name 其中:name 希 ...
- IDEA启动tomcat报java.net.SocketExceptionsocket closed
IDEA启动tomcat报java.net.SocketException:socket closed.如图所示 解决方法:打开任务管理器,检查有没有java.exe进程. 关闭了重新启动就好了 ...
- css5-盒子模型
HTML<!DOCTYPE html><html lang="en"><head> <link rel="stylesheet& ...
- Android 网络编程(一)
概述 一.Android平台网络相关API接口 1.java.net.*(标准Java接口) java.net.*提供与联网有关的类,包括流.数据包套接字(socket).Internet协议.常见H ...
- 地兵布阵 -----------HDU-1166
C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...
- Python入门(一个有趣的画图例子实战)你肯定不会
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:qiu_fang 画一条可爱的python(蟒蛇): import t ...