观察者模式:顾名思义,就是众多观察者(observers)对被观察者(observable)的状态、行为等进行监听,
当被观察者(observable)的状态、行为等发生改变后,向观察者(observers)发出通知,告知观察者(observers),
观察者可以对这些通知进行处理或者不处理。
举个例子:
比如在上课的时候,老师可以看成一个被观察者(observable),所有学生可以看成观察者(observers)。
老师(observable)喊上课之后,所有同学(observers)的注意力都集中在老师身上,这时候相当于给被观察者(observable)添加了许多观察者(observers);
被观察者(老师)(observable)的一言一行都会通过光或者声音反馈给到同学们(observers),当然同学们(observers)对
老师(observable)的言行可能有所反应或者不做任何响应。比如在看到老师(observable)走过来的时候,没认真听讲的同学(observers)赶紧坐好,集中注意(响应),认真听讲的同学(observers)则可以不做反应。
当然在收到老师(observable)【放学】的通知后,同学们都背起书包回家,即都响应了。
从上面例子可以看出,观察者(observers)一定要有接收被观察者(observable)通知的能力;
被观察者(observable)一定要有增加观察者(observers)的和通知观察者(observers)的能力;
那么我们可以将这些能力抽象出来,让具体的实现必须实现这些能力,然后添加观察者(observers)的时候
只关心他有没有接收通知的能力(即是否是抽象观察者类observers的实现类)。至此,以及结合高内聚低耦合的思想,我们可以看到,
观察者模式有4个必要元素:
1.观察者抽象类
2.观察者具体实现类
3.被观察者抽象类
4.被观察者具体实现类
下面来具体实现以下:
观察者抽象类:
public abstract class Observerabstract {
/**
* 必须有接收通知的能力
* @param msg
*/
abstract void update(String msg);
}
观察者具体实现类:
public class MyObserver extends Observerabstract {
//传入名称,区分不同的观察者
private String name;
public MyObserver(String name) {
this.name = name;
}
@Override
public void update(String msg) {
System.out.print(String.format("%s 收到了新消息: %s \n",name,msg));
// System.out.print(name+ "收到特急书信: "+msg);
// Log.i("魔教求助信",name+ "收到特急书信: "+msg);
}
}
被观察者抽象类:
public abstract class Observableabstract {
/**
* 增加观察者
* @param observer 观察者实例对象
*/
abstract void add(Observerabstract observer);
/**
* 移除观察者
* @param observer 需要移除的观察者对象
*/
abstract void move(Observerabstract observer);
/**
* 数据变更是通知观察者
*/
abstract void notifyObserver();
}
被观察者具体实现类:
public class MyObservable extends Observableabstract {
//保存有多少个观察者要对此被观察者进行观察
private List observerList;
private String message;
public MyObservable() {
observerList = new ArrayList<>();
}
@Override
public void add(Observerabstract observer) {
observerList.add(observer);
}
@Override
public void move(Observerabstract observer) {
observerList.remove(observer);
}
@Override
public void notifyObserver() {
for (Observerabstract observer:observerList){
observer.update(message);
}
}
public void setMessage(String message) {
this.message = message;
notifyObserver();
}
}
再来看看咱们recycleview的adapter中的源码
观察者抽象类:
/**
* Observer base class for watching changes to an {@link Adapter}.
* See {@link Adapter#registerAdapterDataObserver(AdapterDataObserver)}.
*/
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, @Nullable 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;
processDataSetCompletelyChanged(true);
if (!mAdapterHelper.hasPendingUpdates()) {
requestLayout();
}
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)) {
triggerUpdateProcessor();
}
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeInserted(positionStart, itemCount)) {
triggerUpdateProcessor();
}
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeRemoved(positionStart, itemCount)) {
triggerUpdateProcessor();
}
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeMoved(fromPosition, toPosition, itemCount)) {
triggerUpdateProcessor();
}
}
void triggerUpdateProcessor() {
if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {
ViewCompat.postOnAnimation(RecyclerView.this, mUpdateChildViewsRunnable);
} else {
mAdapterUpdateDuringMeasure = true;
requestLayout();
}
}
}
被观察者抽象类:
/**
* Provides methods for registering or unregistering arbitrary observers in an {@link ArrayList}.
*
* This abstract class is intended to be subclassed and specialized to maintain
* a registry of observers of specific types and dispatch notifications to them.
*
* @param T The observer type.
*/
public abstract class Observable {
/**
* The list of observers. An observer can be in the list at most
* once and will never be null.
*/
protected final ArrayList mObservers = new ArrayList();
/**
* Adds an observer to the list. The observer cannot be null and it must not already
* be registered.
* @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();
}
}
}
被观察者具体实现类:
static class AdapterDataObservable extends Observable {
public boolean hasObservers() {
return !mObservers.isEmpty();
}
public void notifyChanged() {
// since onChanged() is implemented by the app, it could do anything, including
// removing itself from {@link mObservers} - and that could cause problems if
// an iterator is used on the ArrayList {@link mObservers}.
// to avoid such problems, just march thru the list in the reverse order.
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
public void notifyItemRangeChanged(int positionStart, int itemCount) {
notifyItemRangeChanged(positionStart, itemCount, null);
}
public void notifyItemRangeChanged(int positionStart, int itemCount,
@Nullable Object payload) {
// since onItemRangeChanged() is implemented by the app, it could do anything, including
// removing itself from {@link mObservers} - and that could cause problems if
// an iterator is used on the ArrayList {@link mObservers}.
// to avoid such problems, just march thru the list in the reverse order.
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload);
}
}
public void notifyItemRangeInserted(int positionStart, int itemCount) {
// since onItemRangeInserted() is implemented by the app, it could do anything,
// including removing itself from {@link mObservers} - and that could cause problems if
// an iterator is used on the ArrayList {@link mObservers}.
// to avoid such problems, just march thru the list in the reverse order.
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeInserted(positionStart, itemCount);
}
}
public void notifyItemRangeRemoved(int positionStart, int itemCount) {
// since onItemRangeRemoved() is implemented by the app, it could do anything, including
// removing itself from {@link mObservers} - and that could cause problems if
// an iterator is used on the ArrayList {@link mObservers}.
// to avoid such problems, just march thru the list in the reverse order.
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeRemoved(positionStart, itemCount);
}
}
public void notifyItemMoved(int fromPosition, int toPosition) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeMoved(fromPosition, toPosition, 1);
}
}
}
很像吧,还有很多地方都用的观察者模式呢,比如jetpack里面!