设计模式之---观察者模式简单分析
来源:互联网 发布:全国省份数据库 编辑:程序博客网 时间:2024/06/05 07:13
- 定义
- 使用场景
- 实例
- 源码分析
- Android源码中观察者
定义
观察者模式是一个使用率非常高的模式,他的一个重要作用就是用来解耦。它是一种一对多的依赖关系,当被观察者发生改变,所以的观察者都会收到通知
使用场景
有很多,如事件多级触发场景,关联行为场景,夸系统的消息交换场景,如消息队列,时间总线的处理机制
实例
/** * Created by zxa on 2017/3/21. * 观察者 */public class Visitor implements Observer{ public String name ; @Override public String toString() { return "AdWall{" + "name='" + name + '\'' + '}'; } public Visitor(String name) { this.name = name; } @Override public void update(Observable o, Object arg) { Log.i("Visitor",o.toString()+"--"+name + ":广告墙 ,更新内容了,内容:" + arg); }}/** * Created by zxa on 2017/3/21. * 这个类是被观察者的角色,相当于广告墙 */public class AdvWall extends Observable { @Override public String toString() { return "AdvWall='" + boss; } public String boss = "boss说:"; public AdvWall() { } public void publicationNews(String content){ setChanged(); notifyObservers(content); }}public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); AdvWall advWall = new AdvWall(); Visitor v_1 = new Visitor("visitor_1"); Visitor v_2 = new Visitor("visitor_2"); Visitor v_3 = new Visitor("visitor_3"); Visitor v_4 = new Visitor("visitor_4"); Visitor v_5 = new Visitor("visitor_5"); advWall.addObserver(v_1); advWall.addObserver(v_2); advWall.addObserver(v_3); advWall.addObserver(v_4); advWall.addObserver(v_5); advWall.publicationNews("广告墙更新了,新的职位出来了,赶紧投简历-----手慢无"); }}
运行结果如下:
03-21 11:44:21.903 17004-17004/com.example.zxa.myapplication I/coder: hi,o:AdvWall{boss=’boss说:’}–visitor_1:广告墙 ,更新内容了,内容:广告墙更新了,新的职位出来了,赶紧投简历—–手慢无
03-21 11:44:21.903 17004-17004/com.example.zxa.myapplication I/coder: hi,o:AdvWall{boss=’boss说:’}–visitor_2:广告墙 ,更新内容了,内容:广告墙更新了,新的职位出来了,赶紧投简历—–手慢无
03-21 11:44:21.903 17004-17004/com.example.zxa.myapplication I/coder: hi,o:AdvWall{boss=’boss说:’}–visitor_3:广告墙 ,更新内容了,内容:广告墙更新了,新的职位出来了,赶紧投简历—–手慢无
03-21 11:44:21.903 17004-17004/com.example.zxa.myapplication I/coder: hi,o:AdvWall{boss=’boss说:’}–visitor_4:广告墙 ,更新内容了,内容:广告墙更新了,新的职位出来了,赶紧投简历—–手慢无
03-21 11:44:21.903 17004-17004/com.example.zxa.myapplication I/coder: hi,o:AdvWall{boss=’boss说:’}–visitor_5:广告墙 ,更新内容了,内容:广告墙更新了,新的职位出来了,赶紧投简历—–手慢无
源码分析
Observer是一个接口只有一个抽象方法void update(Observable o, Object arg);
下面的注释大体上说:
一个类想成为观察者希望被通知,就要实现
/** * A class can implement the <code>Observer</code> interface when it * wants to be informed of changes in observable objects. * * @author Chris Warth * @see java.util.Observable * @since JDK1.0 */public interface Observer { /** * This method is called whenever the observed object is changed. An * application calls an <tt>Observable</tt> object's * <code>notifyObservers</code> method to have all the object's * observers notified of the change. * * @param o the observable object. * @param arg an argument passed to the <code>notifyObservers</code> * method. */ void update(Observable o, Object arg);}
Observable中保存了一个observers = new ArrayList<>();集合,用来保存观察者对象
setChanged clearChanged分别用来设置标志位
/** * Marks this <tt>Observable</tt> object as having been changed; the * <tt>hasChanged</tt> method will now return <tt>true</tt>. */ protected synchronized void setChanged() { changed = true; } /** * Indicates that this object has no longer changed, or that it has * already notified all of its observers of its most recent change, * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>. * This method is called automatically by the * <code>notifyObservers</code> methods. * * @see java.util.Observable#notifyObservers() * @see java.util.Observable#notifyObservers(java.lang.Object) */ protected synchronized void clearChanged() { changed = false; }
notifyObservers用来通知各个观察者有新的内容更新,最主要通过changed这个标志位来标记。
/** * If this object has changed, as indicated by the * <code>hasChanged</code> method, then notify all of its observers * and then call the <code>clearChanged</code> method to indicate * that this object has no longer changed. * <p> * Each observer has its <code>update</code> method called with two * arguments: this observable object and the <code>arg</code> argument. * * @param arg any object. * @see java.util.Observable#clearChanged() * @see java.util.Observable#hasChanged() * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void notifyObservers(Object arg) { /* * a temporary array buffer, used as a snapshot of the state of * current Observers. */ Observer[] arrLocal; synchronized (this) { /* We don't want the Observer doing callbacks into * arbitrary Observables while holding its own Monitor. * The code where we extract each Observable from * the ArrayList and store the state of the Observer * needs synchronization, but notifying observers * does not (should not). The worst result of any * potential race-condition here is that: * * 1) a newly-added Observer will miss a * notification in progress * 2) a recently unregistered Observer will be * wrongly notified when it doesn't care */ if (!hasChanged()) return; arrLocal = observers.toArray(new Observer[observers.size()]); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) arrLocal[i].update(this, arg); }
Android源码中观察者
BaseAdapter中就有个被观察者如下:
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter { // 这里相当于上面的AdvWall类 private final DataSetObservable mDataSetObservable = new DataSetObservable(); public boolean hasStableIds() { return false; } public void registerDataSetObserver(DataSetObserver observer) { mDataSetObservable.registerObserver(observer); } public void unregisterDataSetObserver(DataSetObserver observer) { mDataSetObservable.unregisterObserver(observer); }
那观察者在哪里呢? 我们看下
@Override public void setAdapter(ListAdapter adapter) { if (mAdapter != null && mDataSetObserver != null) { //这里解注册 mAdapter.unregisterDataSetObserver(mDataSetObserver); } resetList(); mRecycler.clear(); if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) { mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, adapter); } else { mAdapter = adapter; } mOldSelectedPosition = INVALID_POSITION; mOldSelectedRowId = INVALID_ROW_ID; // AbsListView#setAdapter will update choice mode states. super.setAdapter(adapter); if (mAdapter != null) { mAreAllItemsSelectable = mAdapter.areAllItemsEnabled(); mOldItemCount = mItemCount; mItemCount = mAdapter.getCount(); checkFocus(); //这里new了一个观察者 并且注册 mDataSetObserver = new AdapterDataSetObserver(); mAdapter.registerDataSetObserver(mDataSetObserver); --------}
下面看下AdapterDataSetObserver的实现
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中的onChanged()的实现如下
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(); //这句话比较关键,是重新测量布局 }
综上所述,观察者在实际的开发中运用的非常的多,希望大家理解并熟练运用
注:本文参考 【Android源码设计模式】
- 设计模式之---观察者模式简单分析
- 设计模式之观察者模式简单理解
- 设计模式之观察者模式简单运用
- 简单理解设计模式之观察者模式
- 设计模式之-观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- SVM 支持向量机(3) SMO算法小结
- JAVA字符串转化为数字(可以适合大部分)
- 32.日志文件
- caffe ubuntu14.04 截屏版
- RecyclerView 练习(二)
- 设计模式之---观察者模式简单分析
- 把外部文件拷贝的AVD安卓模拟器上的sdcard上,并且在AVD中浏览sdcard的文件
- java环境变量配置
- PAT L2-012. 关于堆的判断
- Java中的CopyOnWrite容器
- 最大公约数的计算____C++
- java语言基础(22)——面向对象(匿名对象的使用)
- <39>python学习笔记——键盘鼠标
- Mybatis如何加载配置文件 源码解读parameterType