观察者模式
- 定义了对象之间一对多的关系。
- 被观察者(主题)用一个公共的接口来更新观察者。
- 被观察者 / 观察者之间松耦合,被观察者不知道观察者的细节,只知道观察者实现了观察者接口即可。
使用一个小例子解释一下观察者模式:
类图:
1,创建接口
- 被观察者
/**
* 被观察者接口
*/
public interface MObservable {
void addObserve(MObserve mobserve);//添加一个观察者
void removeObserve(MObserve mobserve);//添加一个观察者
void notifyObserver(String info);//传达给观察者的消息
}
- 观察者接口
/**
* 观察者 接口
*/
public interface MObserve {
void upData(String info);
}
2,创建具体的实现类
- 具体的被观察者
/**
* 具体的被观察者(主题)
*/
public class WeatherData implements MObservable{
private List<MObserve> mObserveList=new ArrayList<>();
@Override
public void addObserve(MObserve mobserve) {
// TODO Auto-generated method stub
mObserveList.add(mobserve);
}
@Override
public void removeObserve(MObserve mobserve) {
// TODO Auto-generated method stub
mObserveList.remove(mobserve);
}
@Override
public void notifyObserver(String info) {
for(int i=0;i<mObserveList.size();i++) {
mObserveList.get(i).upData(info);
}
}
}
- 具体的观察者
/**
* 具体的观察者
* @author cuishuxiang
*/
public class NormalObserve implements MObserve{
@Override
public void upData(String info) {
// TODO Auto-generated method stub
System.out.println("观察者:NormalObserve 接收到了:"+info);
}
}
3,测试类
/**
* 观察者模式:测试类
*/
public class ObserveTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
MObservable mWeatherData=new WeatherData();
//添加一个观察者
MObserve normal_1=new NormalObserve();
mWeatherData.addObserve(normal_1);
//添加一个观察者
MObserve normal_2=new NormalObserve2();
mWeatherData.addObserve(normal_2);
//给观察者发送消息
mWeatherData.notifyObserver("我是被观察者!!!");
}
}
结果如下:
简单分析一下Android 列表notify方法的观察者模式
Android RecyclerView列表刷新的时候,也是用到了观察者模式。个人理解:列表中的每一个Item子项都是一个观察者,被观察者可以理解成RecyclerView的Adapter适配器这个控件,当Adapter调用了notify()方法,每一个观察者(列表的item)就会被通知进行相应操作(如刷新)。
拿出RecyclerView的部分源码进行一下分析:
1,观察者
- 抽象的观察者
/**
* 抽象观察者
*/
public abstract static class AdapterDataObserver {
public void onChanged() {
// Do nothing,实现在具体的观察者中
}
....
public void onItemRangeChanged(int positionStart, int itemCount) {
// do nothing
}
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
// fallback to onItemRangeChanged(positionStart, itemCount) if app
// does not override this method.
onItemRangeChanged(positionStart, itemCount);
}
public void onItemRangeInserted(int positionStart, int itemCount) {
// do nothing
}
public void onItemRangeRemoved(int positionStart, int itemCount) {
// do nothing
}
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
// do nothing
}
.....
}
- 具体的观察者
/**
* 具体观察者
*/
private class RecyclerViewDataObserver extends AdapterDataObserver {
RecyclerViewDataObserver() {
}
.....
@Override
public void onChanged() {
assertNotInLayoutOrScroll(null);
mState.mStructureChanged = true;
setDataSetChangedAfterLayout();
if (!mAdapterHelper.hasPendingUpdates()) {
requestLayout();
}
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)) {
triggerUpdateProcessor();
}
}
........
}
2,被观察者
- 抽象的被观察者
/**
* 抽象的被观察者
* 使用的是 Android 包下面的 Observable
*/
public abstract class Observable<T> {
/**
* 使用一个List,将注册的观察者存储
*/
protected final ArrayList<T> mObservers = new ArrayList<T>();
/**
* 添加一个观察者到List中,具体的观察者也是调用的该方法
*
* @param observer the observer to register
* @throws IllegalArgumentException the observer is null
* @throws IllegalStateException the observer is already registered
*/
public void registerObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
if (mObservers.contains(observer)) {
throw new IllegalStateException("Observer " + observer + " is already registered.");
}
mObservers.add(observer);
}
}
/**
* Removes a previously registered observer. The observer must not be null and it
* must already have been registered.
* @param observer the observer to unregister
* @throws IllegalArgumentException the observer is null
* @throws IllegalStateException the observer is not yet registered
*/
public void unregisterObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
int index = mObservers.indexOf(observer);
if (index == -1) {
throw new IllegalStateException("Observer " + observer + " was not registered.");
}
mObservers.remove(index);
}
}
/**
* Remove all registered observers.
*/
public void unregisterAll() {
synchronized(mObservers) {
mObservers.clear();
}
}
}
- 具体的被观察者
/**
* 抽象的被观察者 继承 android包下的 被观察者
* Observable<T> T 为观察者的类型
*
*/
static class AdapterDataObservable extends Observable<AdapterDataObserver> {
...
public void notifyChanged() {
/**
* 在这里调用循环所有观察者的 onChange();方法
*/
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
....
}
3,调用(相当于上面例子的测试类)
/**
* RecyclerView . Adapter
* 调用 notifyDataSetChanged() -----> 相当于例子中的Test类
*/
public abstract static class Adapter<VH extends ViewHolder> {
private final AdapterDataObservable mObservable = new AdapterDataObservable();
private boolean mHasStableIds = false;
....
/**
* 注册观察者(面向接口编程;依赖倒置原则)
*
*/
public void registerAdapterDataObserver(AdapterDataObserver observer) {
mObservable.registerObserver(observer);
}
/**
* 解除观察者
*/
public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
mObservable.unregisterObserver(observer);
}
/**
* 当状态改变时,通知所有的观察者
*/
public final void notifyDataSetChanged() {
mObservable.notifyChanged();
}
.....
}
依赖倒置原则
依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
个人理解:在方法中传入对象的时候,尽量使用它顶层的抽象来作为参数,如上例中的:被观察者添加观察者的情况,声明的是观察者的抽象接口,而不是具体的观察者(这样以来不同的观察者只需实现该接口/抽象类,就可以添加到被观察者中)。
//添加观察者这里声明的是观察者的接口
void addObserve(MObserve mobserve);
//AdapterDataObserver 也是一个抽象的观察者类
public void registerAdapterDataObserver(AdapterDataObserver observer)