1.定义
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象得到通知并被自动更新。
2.UML
观察者模式说明:
- 1.subject 抽象主题,也就是被观察(observable)角色,抽象主题角色把所有观察者对象引用到一个集合
- 2.concteteSubject:具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发送改变时,通知注册过观察者发出通知,也叫具体被观察者。
- 3.observer:抽象观察者,该角色是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改时更新自己
- 4.concreteObserver:具体的观察者。
3.使用场景
- 1.关联行为场景,需要注意的是关联行为是可以分拆的,而不是组合关系
- 2.事件多级触发场景
- 3.跨系统的消息交换场景,如消息队列,事件总线的处理机制
4.两种模式
-
推模型:主题对象向观察者推主题的详细信息,不管观察者是否需要,推送的信息通畅是主题对象的全部或者部分
-
拉模型:主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当是观察者从主题中拉对象数据。一般这种模型的实现,会包主题对象通过update方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用获取。
注意: 就是是否把整体传递给观察者
5.代码实现
1.抽象subject
//主推模式
public abstract class Subject {
// 用来保存注册的观察者对象
private List<Observer> list = new ArrayList<Observer>();
/**
* 注册观察者对象
*
* @param observer
*/
public void attach(Observer observer) {
if (observer != null) {
list.add(observer);
}
System.out.println("Attach observer");
}
/**
* 删除观察者
*
* @param observer
*/
public void detach(Observer observer) {
if (observer != null) {
list.remove(observer);
}
System.out.println("Detach observer");
}
/**
* 通知所有注册的观察者更新状态
*
* @param newState
*/
public void nodifyObserver(String newState) {
for (Observer observer : list) {
observer.update(newState);
}
}
}
拉模式
/**
* 通知所有注册的观察者更新状态
*
*/
public void nodifyObserver() {
for (Observer observer : list) {
observer.update(this);
}
}
2.具体实现 concreteSubject
//推模式
public class ConcreteSubject extends Subject {
private String state;
public String getState() {
return state;
}
public void change(String newState){
state = newState;
System.out.println("主题状态为:" + state);
//状态发生改变,通知各个观察者
nodifyObserver(newState);
}
}
//拉模式
public class ConcreteSubject extends Subject {
private String state;
public String getState() {
return state;
}
public void change(String newState){
state = newState;
System.out.println("主题状态为:" + state);
//状态发生改变,通知各个观察者
nodifyObserver();
}
}
3.抽象observer
//推模式
public interface Observer {
public void update(String newState);
}
//拉模式
public interface Observer {
public void update(Subject subject);
}
4.具体的observer
//推模式
public class ConcreteObserver implements Observer {
// 观察者的状态
private String observerState;
// 观察者的状态
private String observerName;
public ConcreteObserver(String name) {
observerName = name;
}
@Override
public void update(String newState) {
/**
* 更新观察者的状态,使其与目标的状态保持一致
*/
observerState = newState;
System.out.println(observerName + " 状态为:" + observerState);
}
}
//拉模式
public class ConcreteObserver implements Observer {
// 观察者的状态
private String observerState;
// 观察者的状态
private String observerName;
public ConcreteObserver(String name) {
observerName = name;
}
@Override
public void update(Subject subject) {
/**
* 更新观察者的状态,使其与目标的状态保持一致
*/
observerState = ((ConcreteSubject)subject).getState();
System.out.println(observerName + " 状态为:" + observerState);
}
}
5.调用方法
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// 创建主题对象
ConcreteSubject subject = new ConcreteSubject();
// 创建观察者对象
Observer observer1 = new ConcreteObserver("test1");
Observer observer2 = new ConcreteObserver("test2");
// 将观察者对象登记到主题对象上
subject.attach(observer1);
subject.attach(observer2);
// 改变主题对象的状态
subject.change("new state");
}
}
6.android源码中的实现
BaseAdapter
1.抽象观察者
抽象观察者public abstract class Observable<T> {
/**
* The list of observers. An observer can be in the list at most
* once and will never be null.
*/
protected final ArrayList<T> mObservers = new ArrayList<T>();
/**
* 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();
}
}
}
2.具体实现observer
观察者集合
3.真正的抽象观察者
抽象观察者
4.其他需要关键适配的都可以继承这个类
5.以ListView的setAdapter为例。
ListView
6.AdapterDataSetObserver 在ListView父类AbsListView中定义
class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {
@Override
public void onChanged() {
super.onChanged();
if (mFastScroll != null) {
mFastScroll.onSectionsChanged();
}
}
@Override
public void onInvalidated() {
super.onInvalidated();
if (mFastScroll != null) {
mFastScroll.onSectionsChanged();
}
}
}
AdapterDataSetObserver是继承DataSetObserver并实现了。
class AdapterDataSetObserver extends DataSetObserver {
private Parcelable mInstanceState = null;
@Override
public void onChanged() {
mDataChanged = true;
mOldItemCount = mItemCount;
mItemCount = getAdapter().getCount();
// Detect the case where a cursor that was previously invalidated has
// been repopulated with new data.
if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
&& mOldItemCount == 0 && mItemCount > 0) {
AdapterView.this.onRestoreInstanceState(mInstanceState);
mInstanceState = null;
} else {
rememberSyncState();
}
checkFocus();
requestLayout();
}
@Override
public void onInvalidated() {
mDataChanged = true;
if (AdapterView.this.getAdapter().hasStableIds()) {
// Remember the current state for the case where our hosting activity is being
// stopped and later restarted
mInstanceState = AdapterView.this.onSaveInstanceState();
}
// Data is invalid so we should reset our state
mOldItemCount = mItemCount;
mItemCount = 0;
mSelectedPosition = INVALID_POSITION;
mSelectedRowId = INVALID_ROW_ID;
mNextSelectedPosition = INVALID_POSITION;
mNextSelectedRowId = INVALID_ROW_ID;
mNeedSync = false;
checkFocus();
requestLayout();
}
public void clearSavedState() {
mInstanceState = null;
}
}
8.流程
流程
在RecyclerView中原理是一样的
- 1.在swapAdapter(Adapter adapter, boolean removeAndRecycleExistingViews)中 adapter是Adapter<VH extends ViewHolder>。
- 2.在其中定义了一个抽象被观察者AdapterDataObservable mObservable = new AdapterDataObservable() 这个被观察者继承AdapterDataObservable extends Observable<AdapterDataObserver>。
- 3.AdapterDataObserver 就是抽象观察者
- 4.RecyclerViewDataObserver是具体的观察者
网友评论