观察者设计模式
来源:互联网 发布:haoduofuli新域名 编辑:程序博客网 时间:2024/06/02 00:28
1. 概述
观察者模式定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。
Android 开发中一个比较典型的例子是点击监听器OnClickListener 。对设置 OnClickListener 来说, View 是被观察者, OnClickListener 是观察者,二者通过setOnClickListener() 方法达成订阅关系。订阅之后用户点击按钮的瞬间,Android Framework 就会将点击事件发送给已经注册的OnClickListener 。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。当然,这也得益于我们可以随意定制自己程序中的观察者和被观察者
观察者模式可以看作是一种通知机制,可以实现一处通知,多处改变
2. Java API提供的观察者模式的实现
2.1 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; synchronized (this) { if (hasChanged()) { clearChanged(); size = observers.size(); arrays = new Observer[size]; observers.toArray(arrays); } } if (arrays != null) { for (Observer observer : arrays) { observer.update(this, data); } } } protected void setChanged() { changed = true; }}
- 原理很简单,Observable中创建了一个List集合,用于存储观察者
- addObserver添加观察者:往List集合中添加一个观察者对象
- deleteObserver删除观察者:从List集合中删除一个观察者对象
- notifyObservers更新数据:遍历List集合,调用观察者对象的update()方法,通知每一个观察者数据的更新
2.2 Observer观察者
public interface Observer { /** * This method is called if the specified {@code Observable} object's * {@code notifyObservers} method is called (because the {@code Observable} * object has been updated. * * @param observable * the {@link Observable} object. * @param data * the data passed to {@link Observable#notifyObservers(Object)}. */ void update(Observable observable, Object data);}
Observer接口只有一个方法,就是通知数据更新的方法update()
通常情况下,我们不会使用系统提供的观察者模式,因为使用java api提供的观察者模式,必须去继承Observable,而由于java单继承的局限性,所以我们一般情况下都是自己去实现观察者模式。其实系统提供的观察者模式很简单,我们自己去实现的时候,只需要模仿着java api写就可以了。
3. 观察者模式的实现
3.1 Observable
public class Teacher { public String message; //发布消息 public void publishMessage(String message) { this.message = message; notifyObservers(message); } List<MyObserver> observers = new LinkedList<>(); //添加观察者 public void addObserver(MyObserver observer) { if (observer == null) { throw new NullPointerException("observer is null"); } else synchronized (this) { if (!observers.contains(observer)) { observers.add(observer); } } } //删除观察者 public synchronized void deleteObserver(MyObserver observer) { observers.remove(observer); } //通知观察者数据改变 public void notifyObservers(String message) { for (MyObserver observer : observers) { observer.update(message); } } }
3.2 Observer
public interface MyObserver { void update(String message); }
public class Student implements Teacher.MyObserver { @Override public void update(String message) { System.out.println(getClass().getSimpleName()+"收到"+message); } }
3.3 观察者模式的使用
public class Test { public static void main(String[] args){ Teacher teacher = new Teacher(); Student student = new Student(); teacher.addObserver(student); teacher.publishMessage("同学们,今天没有作业"); } }
4. ListView中的观察者模式
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(); } public void notifyDataSetInvalidated() { mDataSetObservable.notifyInvalidated(); }}
DataSetObservable
public class DataSetObservable extends Observable<DataSetObserver> { public void notifyChanged() { synchronized(mObservers) { for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onChanged(); } } } public void notifyInvalidated() { synchronized (mObservers) { for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onInvalidated(); } } }}
DataSetObserver
public abstract class DataSetObserver { public void onChanged() { } public void onInvalidated() { }}
AdapterView
public abstract class AdapterView<T extends Adapter> extends ViewGroup { class AdapterDataSetObserver extends DataSetObserver { }}
AbsListView
public abstract class AbsListView extends AdapterView<ListAdapter>{ class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver { }}
5. 观察者模式的应用
- RxJava
- Data Binding
- EventBus
- Broadcast
- Loader
- ListView
- GridView
- RecyclerView
- Loader
- 模式设计:观察者模式
- 设计模式-----观察者模式
- 设计模式-观察者模式
- 设计模式--观察者模式
- 设计模式:观察者模式
- 设计模式-----观察者模式
- 设计模式:观察者模式
- 设计模式-观察者模式
- 设计模式 观察者模式
- 设计模式-观察者模式
- 设计模式-【观察者模式】
- 设计模式-观察者模式
- 设计模式 -- 观察者模式
- 设计模式-观察者模式
- 【设计模式】观察者模式
- 设计模式- 观察者模式
- 设计模式- 观察者模式
- 设计模式--观察者模式
- 简单的Windows Webcam应用:Barcode Reader
- 6-1 多态性与虚函数
- memcached安装说明
- python数据质量分析小例子
- 7.Android基础:四大组件之----->ContentProvider
- 观察者设计模式
- 解决nginx+php(php-fpm)出现502 bad gateway问题
- 超Easy!!! Git入门
- 关于myeclipse10.7破解的问题(破解不成功显示只有五天可用可激活)
- 【web】js添加附件功能(显示进度条)——添加附件-demo01
- const的位置和不同位置产生的区别
- Java数组-冒泡排序2
- 解决ajax跨域访问 为了方便以后查看
- EventBus使用详解(一)——初步使用EventBus