设计模式--观察者模式
来源:互联网 发布:背四级英语单词的软件 编辑:程序博客网 时间:2024/05/21 22:36
定义?
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。
观察者模式的作用是什么?
观察者模式的主要作用就是对象解耦,将观察者和被观察者完全隔离,只依赖于Observer和Observable抽象。
观察者模式的简单实现
很多技术网站支持用户邮箱订阅,每周发布周报后会将优质的内容推送给订阅用户。
/** * 程序员是观察者 */ public class Coder implements Observer { public String name; public Coder(String name) { this.name = name; } @Override public void update(Observable observable, Object data) { System.out.print(name + data); } @Override public String toString() { return name; } }
/** * 技术网站是被观察者,当它有更新时所有的观察者(程序员)都会接收到相应的通知 */ public class DevTechFrontier extends Observable { public void postNewPublication(String content) { //标示状态,内容发生改变 setChanged(); //通知所有的观察者 notifyObservers(); } }
/** * 测试代码 */ public class Test { public void main(String[] args) { //被观察者 DevTechFrontier devTechFrontier=new DevTechFrontier(); //观察者 Coder coder1=new Coder("coder-1"); Coder coder2=new Coder("coder-2"); Coder coder3=new Coder("coder-3"); //将观察者注册到列表中 devTechFrontier.addObserver(coder1); devTechFrontier.addObserver(coder2); devTechFrontier.addObserver(coder3); //发布消息 devTechFrontier.postNewPublication("新的一期技术周报发布了!"); } }
输出结果:
coder-1,新的一期技术周报发布了!
coder-2,新的一期技术周报发布了!
coder-3,新的一期技术周报发布了!
可以看到,所有订阅的用户都收到了更新消息,一对多的订阅。
这里Observer是抽象的观察者,Coder是具体的观察者;Observable是抽象被观察者,DevTechFrontier 是具体的可观察对象。Coder是观察者,它们订阅了DevTechFrontier 这个具体的可观察对象,当DevTechFrontier 有更新时,会遍历所有的观察者Coder,然后给这些观察者发布一个更新消息,即调用Coder的update方法,这样就达到了一对多的通知功能。在这个通知过程中,通知系统都是依赖Observer和Observable这两个抽象类,因此,对于Coder和DevTechFrontier 完全没有耦合。
JDK中的Observer接口和Observable类实现
1.在Observer接口源代码中只声明一个update()方法
public interface Observer { void update(Observable var1, Object var2);}
被观察者的对象当改变时调用这个方法。实现这个接口的类,可以作为观察者。
2.Observable类,被观察者,消息的发出者,继承此类可以扩展。
public class Observable { //观察者的集合 List<Observer> observers = new ArrayList<Observer>(); boolean changed = false; public Observable() { } public void addObserver(Observer observer) { if (observer == null) { throw new NullPointerException("observer == null"); } synchronized (this) { if (!observers.contains(observer)) observers.add(observer); } } protected void clearChanged() { changed = false; } public int countObservers() { return observers.size(); } public synchronized void deleteObserver(Observer observer) { observers.remove(observer); } public synchronized void deleteObservers() { observers.clear(); } public boolean hasChanged() { return changed; } public void notifyObservers() { notifyObservers(null); } //通知所有订阅此主题的观察者对象 @SuppressWarnings("unchecked") public void notifyObservers(Object data) { int size = 0; Observer[] arrays = null; //这里为啥要同步? //保证observers集合的数据唯一 synchronized (this) { if (hasChanged()) { clearChanged(); size = observers.size(); arrays = new Observer[size]; observers.toArray(arrays); } } //这里为什么没有同步? //观察者的updata操作可能是耗时操作 if (arrays != null) { for (Observer observer : arrays) { observer.update(this, data); } } } protected void setChanged() { changed = true; }}
Android源码分析
ListView是Android中最重要的控件之一,而ListView最重要的一个功能是Adapter。通常,我们往ListView添加数据后,都会调用Adapter的notifyDataSetChange。下面对这个方法的源码进行分析。
notifyDataSetChange这个方法定义在BaseAdapter中,具体代码如下:
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter { //数据集观察者 private final DataSetObservable mDataSetObservable = new DataSetObservable(); public void registerDataSetObserver(DataSetObserver observer) { mDataSetObservable.registerObserver(observer); } public void unregisterDataSetObserver(DataSetObserver observer) { mDataSetObservable.unregisterObserver(observer); } /** *当数据集发现变化时,通知所有观察者 */ public void notifyDataSetChanged() { mDataSetObservable.notifyChanged(); }}
接下来看mDataSetObservable.notifyChanged()的源码:
/***数据集观察者*/public class DataSetObservable extends Observable<DataSetObserver> { //调用每个观察者的onChanged方法来通知它们被观察者发生了变化 public void notifyChanged() { synchronized(mObservers) { for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onChanged(); } } }}
这部分代码很简单,就是在mDataSetObservable.notifyChanged()中遍历所有的观察者,并且调用它们的onChanged方法,从而告知观察者发生了变化。
- 模式设计:观察者模式
- 设计模式-----观察者模式
- 设计模式-观察者模式
- 设计模式--观察者模式
- 设计模式:观察者模式
- 设计模式-----观察者模式
- 设计模式:观察者模式
- 设计模式-观察者模式
- 设计模式 观察者模式
- 设计模式-观察者模式
- 设计模式-【观察者模式】
- 设计模式-观察者模式
- 设计模式 -- 观察者模式
- 设计模式-观察者模式
- 【设计模式】观察者模式
- 设计模式- 观察者模式
- 设计模式- 观察者模式
- 设计模式--观察者模式
- 数据库索引优缺点
- 用GDB调试程序
- maven安装
- C++面试(五)
- Spring注解@Resource和@Autowired区别对比
- 设计模式--观察者模式
- HDOJ 2054 A == B ?(精确大数相等)
- arcgis空间校正spcial adjustment
- .net中JS、Jquery前后台互动总结
- iOS开发--常用技巧 (MJRefresh详解)
- CSS---堆叠顺序---position---z-index
- 曾响铃:重场景体验下的家居业,考验的究竟是啥?
- 第 7 章 CSS 布局模型
- RabbitMQ Exchange 类型介绍