装载请标明出处: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(抽象观察者)这两个类,我们也可以直接拿来用,具体可以去看看源码。

 
Android中有很多地方也用到了观察者模式:
  • 点击事件
  • listView的刷新
  • 广播等等
 

Android设计模式—观察者模式的更多相关文章

  1. Android设计模式-观察者模式

    原文地址 http://blog.csdn.net/qq_25806863/article/details/69218968 观察者模式是一种使用频率非常高的设计模式,最常用的地方就是订阅-发布系统. ...

  2. Android设计模式---观察者模式小demo(一)

    1,今天刚好看到了设计模式这一块来,而观察者模式是我一直想总结的,先来看看观察者模式的简单的定义吧 "当一个对象改变时,他的所有依赖者都会受到通知,并自动更新." 一般我们项目中就 ...

  3. Android设计模式—— 观察者模式(以及EventBus的简单使用)

    1.概述 观察者模式最常用的地方是GUI系统.订阅-发布系统.观察者模式的一个重要作用就是解耦,将观察者和被观察者解耦,使得他们之间的依赖性更小. 2.定义 定义对象间的一种一对多依赖关系,使得每当一 ...

  4. Android设计模式系列

    http://www.cnblogs.com/qianxudetianxia/category/312863.html Android设计模式系列(12)--SDK源码之生成器模式(建造者模式) 摘要 ...

  5. 经常使用的android设计模式

    一般来说,经常使用的android设计模式有下面8种:单例.工厂.观察者.代理.命令.适配器.合成.訪问者.   单例模式:目的是为了让系统中仅仅有一个调用对象,缺点是单例使其它程序过分依赖它,并且不 ...

  6. 18. 星际争霸之php设计模式--观察者模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  7. Android中观察者模式的升入理解

    以前对Java中的观察者模式只知道一点皮毛,在接触Android的过程中,逐渐认识到观察者模式是如此的重要,android中许多地方都用到了观察者模式例如ContentResolver操作,来总结一下 ...

  8. Android设计模式(五岁以下儿童)--简单工厂模式

    1.面试的时候问这个问题: 在ListView 的item小程序.很多不同的显示风格.或者是,为了更好地维护,不同的样式,应该怎么做? 我一下就想到的是工厂的模式,利用project,编写ViewFa ...

  9. linkin大话设计模式--观察者模式

    linkin大话设计模式--观察者模式 观察者模式定义了对象间的一对多依赖关系,让一个或者多个观察者观察一个对象主题.当主题对象的状态发生改变的时候,系统能通知所有的依赖于此对象的观察者对象,从而能自 ...

随机推荐

  1. Mysql查询语句之排序查询

    语法: /* select 查询列表 from 表 [where 筛选条件] order by 排序列表 [asc/desc] */ ①asc为升序,desc为降序,且默认为升序 ②order by子 ...

  2. 经典sql面试题(学生表_课程表_成绩表_教师表)

    转载:https://www.cnblogs.com/qixuejia/p/3637735.html 表架构 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cna ...

  3. 【Android - 自定义View】之View的位置参数

    View是Android中所有控件的基类,不管是简单的Button和TextView,还是复杂的RelativeLayout和ListView,其基类都是View类:ViewGroup也继承了View ...

  4. 教你如何提高 PHP 代码的质量

    说实话,在代码质量方面,PHP 的压力非常大.通过阅读本系列文章,您将了解如何提高 PHP 代码的质量. 我们可以将此归咎于许多原因,但这肯定不仅仅是因为 PHP 生态系统缺乏适当的测试工具.在本文中 ...

  5. 月下无限连?拒绝无休止switch!

    拒绝无休止switch 一.前言 前天碰到个需求,其实很简单,就是Excel导入,Excel模板长下面这样: 按我平常的逻辑是这样做的: 用文件输入流读取Excel,根据Excel的版本生成不同的对象 ...

  6. JavaScript新手经常遇到的问题(二)

    1.Form表单只提交数据而不进行页面跳转的方法 <script type="text/javascript" src="js/jquery/jquery-1.8. ...

  7. 不服跑个分:ARM鲲鹏云服务器实战评测——华为云鲲鹏KC1实例 vs. 阿里云G5实例【华为云技术分享】

    原文链接:https://m.ithome.com/html/444828.htm 今年一月份,华为正式发布了鲲鹏920数据中心高性能处理器,该处理器兼容ARM架构,采用7纳米制造,最高支持64核,主 ...

  8. 链接脚本(Linker Script)用法解析(一) 关键字SECTIONS与MEMORY

    1.MEMORY关键字用于描述一个MCU ROM和RAM的内存地址分布(Memory Map),MEMORY中所做的内存描述主要用于SECTIONS中LMA和VMA的定义. 2.SECTIONS关键字 ...

  9. list tuple dict 方法

    >>> dir(list)['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir_ ...

  10. 5G,仅仅是更快的网速吗?

    前不久参加了华为的Dev Summit 2020开发者大会,听到了关于5G的一些分享,刚好最近对5G有一些自己的思考,在此分享给大家. 什么是5G 在这里我不想列举各种晦涩难懂的术语,简单说来,5G就 ...