美文网首页
android源码中使用的设计模式(行为型--观察者模式)

android源码中使用的设计模式(行为型--观察者模式)

作者: 田间小鹿 | 来源:发表于2017-12-20 17:45 被阅读0次

    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是具体的观察者

    相关文章

      网友评论

          本文标题:android源码中使用的设计模式(行为型--观察者模式)

          本文链接:https://www.haomeiwen.com/subject/wwugwxtx.html