美文网首页
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