10min初识观察者模式
来源:互联网 发布:阿里云幕布 高清下载 编辑:程序博客网 时间:2024/06/15 23:56
今天学习了Android设计模式源码解析之观察者模式,写一篇读后感,10min快速了解观察者模式。
1.模式的定义
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
2.模式的使用场景
- 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系;
- 事件多级触发场景;
- 跨系统的消息交换场景,如消息队列、事件总线的处理机制。
3.UML类图
角色介绍
抽象主题 (Subject) 角色
抽象主题角色把所有观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。具体主题 (ConcreteSubject) 角色
将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。抽象观察者 (Observer) 角色
为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。具体观察者 (ConcreteObserver) 角色
存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
4. 模式的简单实现
以我们开发者耳熟能详的《CSDN周刊》为例,《CSDN周刊》每周都会发布关于新技术、互联网前沿资讯等内容,在这里我们可以看到最新的技术。这其实就是一个RSS系统,用户订阅《CSDN周刊》的文章,每当有更新的时候将新的内容推送给订阅用户。这不就是观察者模式吗?观察者模式的另一个名字叫做发布-订阅模式,下面让我们来简单模拟一下《CSDN周刊》的发布过程吧!
下面开始源代码的编写:
我们先实现观察者(程序员),实现Observer接口并重写update方法:
package com.quan.Observer;import java.util.Observable;import java.util.Observer;/** * 权兴权意-2016.11.21 * 观察者模式-观察者(程序员) */public class Coder implements Observer{public String name;public Coder(String name) {this.name = name;}@Overridepublic void update(Observable o, Object arg) {System.out.println("Hi," + name + ",《CSDN周刊》更新啦,内容:" + arg);}}
Observer接口源代码:
/* * @(#)Observer.java1.20 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.util;/** * A class can implement the <code>Observer</code> interface when it * wants to be informed of changes in observable objects. * * @author Chris Warth * @version 1.20, 11/17/05 * @see java.util.Observable * @since JDK1.0 */public interface Observer { /** * This method is called whenever the observed object is changed. An * application calls an <tt>Observable</tt> object's * <code>notifyObservers</code> method to have all the object's * observers notified of the change. * * @param o the observable object. * @param arg an argument passed to the <code>notifyObservers</code> * method. */ void update(Observable o, Object arg);}
接下来我们实现被观察者(CSDNWeekly),继承Observable类,使用它的setChanged和notifyObservers方法:
package com.quan.Observer;import java.util.Observable;/** * 权兴权意-2016.11.21 * 观察者模式-被观察者(CSDNWeekly) */public class CSDNWeekly extends Observable{public void postNewPublication(String content){setChanged();//标识改变notifyObservers(content);//通知所有观察者}}
我们可以看一下Observable类的setChanged和notifyObservers方法:
/** * Marks this <tt>Observable</tt> object as having been changed; the * <tt>hasChanged</tt> method will now return <tt>true</tt>. */ protected synchronized void setChanged() {changed = true; }
/** * If this object has changed, as indicated by the * <code>hasChanged</code> method, then notify all of its observers * and then call the <code>clearChanged</code> method to indicate * that this object has no longer changed. * <p> * Each observer has its <code>update</code> method called with two * arguments: this observable object and the <code>arg</code> argument. * * @param arg any object. * @see java.util.Observable#clearChanged() * @see java.util.Observable#hasChanged() * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void notifyObservers(Object arg) {/* * a temporary array buffer, used as a snapshot of the state of * current Observers. */ Object[] arrLocal;synchronized (this) { /* We don't want the Observer doing callbacks into * arbitrary code while holding its own Monitor. * The code where we extract each Observable from * the Vector and store the state of the Observer * needs synchronization, but notifying observers * does not (should not). The worst result of any * potential race-condition here is that: * 1) a newly-added Observer will miss a * notification in progress * 2) a recently unregistered Observer will be * wrongly notified when it doesn't care */ if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); }
最后我们编写测试代码进行测试:
package com.quan.Observer;/** * 权兴权意-2016.11.21 * 观察者模式-测试代码 */public class Test {public static void main(String[] args) {CSDNWeekly csdnWeekly = new CSDNWeekly();Coder coder1 = new Coder("coder1");Coder coder2 = new Coder("coder2");Coder coder3 = new Coder("coder3");csdnWeekly.addObserver(coder1);csdnWeekly.addObserver(coder2);csdnWeekly.addObserver(coder3);csdnWeekly.postNewPublication("《CSDN周刊》-惟楚有才,权兴权意。");}}
输出结果:
Hi,coder3,《CSDN周刊》更新啦,内容:《CSDN周刊》-惟楚有才,权兴权意。
Hi,coder2,《CSDN周刊》更新啦,内容:《CSDN周刊》-惟楚有才,权兴权意。
Hi,coder1,《CSDN周刊》更新啦,内容:《CSDN周刊》-惟楚有才,权兴权意。
可以看到所有订阅了《CSDN周刊》的用户都受到了更新消息,一对多的订阅-发布系统这么简单就完成了。
这里Observer是抽象的观察者角色,Coder扮演的是具体观察者的角色;Observable对应的是抽象主题角色,CSDNWeekly则是具体的主题角色。Coder是具体的观察者,他们订阅了CSDNWeekly这个具体的可观察对象,当CSDNWeekly有更新时,会遍历所有观察者 ( Coder ),然后给这些观察者发布一个更新的消息,即调用Coder中的update方法,这样就达到了1对多的通知功能。Observer和Observable都已经内置在jdk中,可见观察者模式在Java中的重要性。
5.Android源码中的模式实现
ListView是Android中最重要的控件,没有之一。而ListView最重要的一个点就是Adapter,在我们往ListView添加数据后,我们都会调用一个方法: notifyDataSetChanged(), 这是为什么呢? 今天我们就来揭开它的神秘面纱。
AdapterView中有一个内部类AdapterDataSetObserver,在ListView设置Adapter时会构建一个AdapterDataSetObserver,并且注册到Adapter中,这个就是一个观察者。而Adapter中包含一个数据集可观察者DataSetObservable,在数据数量发生变更时开发者手动调用AdapternotifyDataSetChanged,而notifyDataSetChanged实际上会调用DataSetObservable的notifyChanged函数,该函数会遍历所有观察者的onChanged函数。在AdapterDataSetObserver的onChanged函数中会获取Adapter中数据集的新数量,然后调用ListView的requestLayout()方法重新进行布局,更新用户界面。6.优缺点:
优点
- 观察者和被观察者之间是抽象耦合
- 观察者模式需要考虑一下开发效率和运行效率问题,一个被观察者,多个观察者,开发和调试就会比较复杂,而且在 Java 中消息的通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。
- 10min初识观察者模式
- 初识设计模式 chapter 02-观察者模式
- 初识c#---委托,事件和观察者模式(Observer)设计模式
- 1min初识SwipeRefreshLayout
- 设计模式10:观察者模式
- 3min初识ListView(3)-背后的设计模式和知之甚少的小优化
- java设计模式(10)---观察者模式
- 设计模式(10):观察者模式
- Java设计模式10:观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 第五章笔记
- 关于super和this关键字调用构造器的几点总结
- php数据导出为txt文档和导入txt文档解析数据
- JAVA后台程序设计及UTIL.CONCURRENT包的运用
- Restful API 简单示例--HelloWorld
- 10min初识观察者模式
- NOIp2016滚粗记
- excel列下拉自增1的实现方法
- 解决XP下iis5.1访问 IIS 元数据库失败
- markdown编辑器——颜色、大小、字体
- ElasticSearch教程--第十一章:修改您的数据--更新文档
- 第八章笔记
- 【寒江雪】B树的一般知识与简单实现
- 多项式相加