1.观察者模式定义
对象之间的依赖关系,使得当一个对象发生改变的时候,依赖的对象会收到通知进行更新。说白了就是当一个对象的状态发生改变时,对象的状与他相关联的部分态同时也会发生改变。
2.观察者模式角色区分——微信订阅公众号
1.被观察者Observable:公众号
2.具体的被观察者:Android进阶之旅
3.观察者Observer:微信的用户
4.具体的观察者:姚明,詹姆斯...
3.观察者模式小示例
1.被观察者Observable
public class WXPubilishObervable {
// 观察者集合
private List<IWXUser> mWXUsers;
public WXPubilishObervable() {
mWXUsers = new ArrayList<>();
}
/**
* 订阅公众号
* @param wxUser
*/
public void register(IWXUser wxUser){
mWXUsers.add(wxUser);
}
/**
* 解除订阅
* @param wxUser
*/
public void unregister(IWXUser wxUser){
mWXUsers.remove(wxUser);
}
/**
* 推送文章
* @param article
*/
public void updata(String article){
for (IWXUser wxUser : mWXUsers) {
wxUser.push(article);
}
}
}
2.具体的观察者
//具体的公众号 -- Android进阶之旅
public class WXAdvanceObservable extends WXPubilishObervable {
private String article;
public void setArticle(String article) {
this.article = article;
updata(article);
}
}
3.观察者Observer
public interface IWXUser {
void push(String article);
}
4.具体的观察者
public class WXUser implements IWXUser {
private String name;
public WXUser(String name) {
this.name = name;
}
@Override
public void push(String article) {
System.out.println(name + " 收到了一篇文章 " + article);
}
}
5.使用:
public class ObserverTest {
public static void main(String[] args){
//微信公众号 具体的被观察者 -- Android进阶之旅
WXAdvanceObservable wxAdvanceObservable = new WXAdvanceObservable();
WXUser yao = new WXUser("姚明");
WXUser james = new WXUser("詹姆斯");
//注册(订阅) 观察者(用户)
wxAdvanceObservable.register(yao);
wxAdvanceObservable.register(james);
//发布文章,推送
wxAdvanceObservable.setArticle("Android设计模式——模板模式");
//解除订阅
wxAdvanceObservable.unregister(yao);
wxAdvanceObservable.setArticle("Android设计模式——工厂模式");
}
}
打印结果:
4.Android源码中观察者模式
1.我们在使用ListView时,为什么每次添加完数据都要调用Adapter的notifiDaraSetChange()方法? 来看看源码是怎么处理的。
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 class DataSetObservable extends Observable<DataSetObserver> {
//当数据放生改变,通过循环调用每一个注册的观察者的onChange方法,通知进程更新。
//最终调用AdapterDataSetObserver 的onChange方法。 调用requestLayout()重新测量计算View的宽高大小进行绘制。
public void notifyChanged() {
synchronized(mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
}
class AdapterDataSetObserver extends DataSetObserver {
//重点
@Override
public void onChanged() {
mDataChanged = true;
mOldItemCount = mItemCount;
mItemCount = getAdapter().getCount();
if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
&& mOldItemCount == 0 && mItemCount > 0) {
AdapterView.this.onRestoreInstanceState(mInstanceState);
mInstanceState = null;
} else {
rememberSyncState();
}
checkFocus();
//重新布局,测量,摆放,绘制。
requestLayout();
}
}
5.总结
优点:
1.观察者和被观察者之间是抽象耦合,应对业务变化。
缺点:
1.可能会引起多余的数据通知。