前言:最近在研究观察者模式,下面来看下观察者模式由哪几部分组合。(android sdk已经帮我们写好了观察者用到的类)
组成
- 抽象观察者(DataSetObserver)
- 抽象被观察者(Observable)
- 具体被观察者(DataSetObservable):继承了Observable
各部分源码
抽象观察者(DataSetObserver):
public abstract class DataSetObserver {
public void onChanged() {
// Do nothing
}
public void onInvalidated() {
// Do nothing
}
}
说明:抽象观察者源码很简单,定义了观察者要做的方法,具体的内容要求我们去继承这个类,重写里面的方法写具体的逻辑。
抽象被观察者(Observable):因为这是被观察者的基类,所以最基本的功能都在这里实现:
- 1.要有存放观察者列表(不然你怎么去通知观察者干活啊);
- 2.注册观察者的方法(往列表添加观察者);
- 3.注销观察者的方法(在列表删除观察者);
- 4.列表所存对象类型还没定义,为泛型T,要求我们继承这个类的时候去定义,我们来决定让
什么样的类干活
public abstract class Observable<T> {
protected final ArrayList<T> mObservers = new ArrayList<T>();
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);
}
}
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);
}
}
public void unregisterAll() {
synchronized(mObservers) {
mObservers.clear();
}
}
}
说明:在上面已经说得差不多了,这里说下官方的编码规范,在ArrayList官方用了protect、final来修饰存放观察者的列表,protect只能让继承它的子类来使用,final是为了不让这个列表被其他类修改,保证了列表的唯一性,安全性。还有每个方法里面都会对列表mObservers加锁,是为了避免并发访问造成的访问冲突。这些都很值得我们去学习。
具体被观察者(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();
}
}
}
}
说明:这里把泛型T定义为DataSetObserver(抽象观察者)了,说明这个具体被观察者类(DataSetObservable )里面的列表所存放的类型就是DataSetObserver(抽象观察者);继承之后自己还写了个方法notifyChanged(),具体逻辑就是调用列表的所有对象的onChanged()方法