设计模式--[9]观察者模式

来源:互联网 发布:中文翻译拼音软件ios 编辑:程序博客网 时间:2024/06/05 10:16

观察者模式

定义

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

应用场景

有一个事件发生改变,需要通知其他多个对象时.更多的应用于异步回调场景.

代码实现

UML类图结构

代码实践

1.Subject主题

public class Subject {    /**     * 事件持有观察者的集合     */    private List<Observer> observers=new ArrayList<>();    /**     * 事件的状态     */    private String state;    /**     * 增加观察者     */    public void attach(Observer observer){        observers.add(observer);    }    /**     * 遍历通知观察者     */     public void notifyAllObservers(){          for (Observer observer : observers) {             observer.update(state);          }       }    public String getState() {        return state;    }    /**     * 当状态发生改变,通知观察者     */    public void setState(String state) {        this.state = state;        notifyAllObservers();    }   }

2.观察者接口

public interface  Observer {    /**     * 更新观察者的状态     */    public void update(String state);}

3.观察者具体实现

public class Observer1 implements Observer {    @Override    public void update(String state) {        // TODO Auto-generated method stub        System.out.println("Observer1 update:"+state);    }}

4.测试

public class Test {    public static void main(String[] args) {        //新建事件        Subject subject=new Subject();        //新建观察者        Observer observer1=new Observer1();        Observer observer2=new Observer2();        //绑定观察者        subject.attach(observer1);        subject.attach(observer2);        //更新事件状态        subject.setState("我更新了");    }}

5.测试结果

Observer1 update:我更新了Observer2 update:我更新了

ListView中的观察者模式

  • 在adapter中有一个内部类AdapterDataSetObserver,这个就是一个观察者.

  • 在listView.setadapter时候会初始观察者.

  • 在AdapterDataSetObserver的onChanged函数中会获取Adapter中数据集的新数量,然后调用ListView的requestLayout()方法重新进行布局,更新用户界面。

源码分析

参考这是一篇关于listview源码的文章

BaseAdapter 中notifyDataSetChanged 调用的mDataSetObservable.notifyChanged();

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);    }    /**     * Notifies the attached observers that the underlying data has been changed     * and any View reflecting the data set should refresh itself.     * 当数据集用变化时通知所有观察者     */    public void notifyDataSetChanged() {        mDataSetObservable.notifyChanged();    }}

在mDataSetObservable.notifyChanged()中遍历所有观察者,并且调用它们的onChanged方法。

public class DataSetObservable extends Observable<DataSetObserver> {    /**     * Invokes onChanged on each observer. Called when the data set being observed has     * changed, and which when read contains the new state of the data.     */    public void notifyChanged() {        synchronized(mObservers) {            // 调用所有观察者的onChanged方式            for (int i = mObservers.size() - 1; i >= 0; i--) {                mObservers.get(i).onChanged();            }        }    }    ...}

继承自AbsListView的父类AdapterView的AdapterDataSetObserver,

  class AdapterDataSetObserver extends DataSetObserver {        private Parcelable mInstanceState = null;        // 上文有说道,调用Adapter的notifyDataSetChanged的时候会调用所有观察者的onChanged方法,核心实现就在这里        @Override        public void onChanged() {            mDataChanged = true;            mOldItemCount = mItemCount;            // 获取Adapter中数据的数量            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();            // 重新布局ListView、GridView等AdapterView组件            requestLayout();        }        ...        public void clearSavedState() {            mInstanceState = null;        }

总结

所谓观察者模式,就是

多个观察者Observer –>观察attach–> 目标Subject的变化—>并通知刷新update

0 0
原创粉丝点击