Java设计格局观察者模式

1.观望者格局的概念及采用情形
观望者情势是一个使用率非凡高的情势,它最常用的地点是GUI系统,订阅-发布系统。因为那一个格局的一个最重要功效就是解耦,将被观望者和寓目者解耦,使得它们中间的看重更小。
定义:
概念对象间一种一对多的依靠关系,使得每当一个目的改变状态,则就此依赖于它的对象都会赢得通告并被自动更新
动用情状:
涉及行为现象,需要留意的是,关联行为时可拆分的,而不是“组合”关系;
事件多级触发场景
跨系统的新闻互换场景,如消息队列、事件总线的拍卖体制

Paste_Image.png

2. 观察者情势的优缺点
2.1优点
阅览者和被观望者之间是空虚解耦,应对业务转移
提升系统灵活性、可增加性
2.2缺点
在使用阅览者形式时需要考虑一下开发效用和运行功用问题,程序中包括一个被观望者、五个观察者、开发和调试等情节会相比复杂,而且在Java中信息的关照默认是逐一执行,一个观看者卡顿,会潜移默化总体的推行效率,在这种气象下,一般考虑动用异步的艺术
3. 观看者形式的兑现情势

public interface Observer {
    //更新方法
    public void  update();
}```

public class ConcreteObsever implements Observer {
@Override
public void update() {
System.out.println(“接收到音讯,并拓展处理!”);
}
}“`

public abstract class Subject {
    //定义一个观察者数组
    private List<Observer> observers = new ArrayList<>();
    //增加一个观察者
    public void addObserver(Observer o) {
        this.observers.add(o);
    }
    //删除一个观察者
    public void removeObserver(Observer o) {
        this.observers.remove(o);
    }
    //通知所有观察者
    public void notifyObservers() {
        for (Observer o : this.observers) {
            o.update();
        }
    }
}```

public class ConcreteSubject extends Subject {
//具体的业务
public void doSomeThing() {
super.notifyObservers();
}
}“`

public class Test {
    public static void main(String args[]) {
      //创建一个被观察者
        ConcreteSubject subject=new ConcreteSubject();
        Observer obs=new ConcreteObsever();
        subject.addObserver(obs);
        subject.doSomeThing();
    }
}```
**4. 观察者模式在Android中的实际应用**
RecycleView是Android中最重要的控件之一,而RecycleView最重要的一个功能就是Adapter。通过我们往RecycleView添加数据后,都会调用Adapter的notifyDataSetChanged()方法,这是为什么?
首先我们看下Adapter的实现,他是RecycleView的一个内部类。

public static abstract class Adapter<VH extends ViewHolder> {
private final AdapterDataObservable mObservable = new
AdapterDataObservable();
private boolean mHasStableIds = false;
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
public abstract void onBindViewHolder(VH holder, int position);
public void onBindViewHolder(VH holder, int position, List<Object>
payloads) {
onBindViewHolder(holder, position);
}
public final VH createViewHolder(ViewGroup parent, int viewType) {
TraceCompat.beginSection(TRACE_CREATE_VIEW_TAG);
final VH holder = onCreateViewHolder(parent, viewType);
holder.mItemViewType = viewType;
TraceCompat.endSection();
return holder;
}
public final void bindViewHolder(VH holder, int position) {
holder.mPosition = position;
if (hasStableIds()) {
holder.mItemId = getItemId(position);
}
holder.setFlags(ViewHolder.FLAG_BOUND,
ViewHolder.FLAG_BOUND | ViewHolder.FLAG_UPDATE |
ViewHolder.FLAG_INVALID
| ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN);
TraceCompat.beginSection(TRACE_BIND_VIEW_TAG);
onBindViewHolder(holder, position, holder.getUnmodifiedPayloads());
holder.clearPayload();
TraceCompat.endSection();
}
public int getItemViewType(int position) {
return 0;
}
public void setHasStableIds(boolean hasStableIds) {
if (hasObservers()) {
throw new IllegalStateException(“Cannot change whether this adapter has
” +
“stable IDs while the adapter has registered observers.”);
}
mHasStableIds = hasStableIds;
}
public long getItemId(int position) {
return NO_ID;
}
public abstract int getItemCount();
public final boolean hasStableIds() {
return mHasStableIds;
}
public void onViewRecycled(VH holder) {
}
public boolean onFailedToRecycleView(VH holder) {
return false;
}
public void onViewAttachedToWindow(VH holder) {
}
public void onViewDetachedFromWindow(VH holder) {
}
public final boolean hasObservers() {
return mObservable.hasObservers();
}
public void registerAdapterDataObserver(AdapterDataObserver observer)
{
mObservable.registerObserver(observer);
}
public void unregisterAdapterDataObserver(AdapterDataObserver observer)
{
mObservable.unregisterObserver(observer);
}
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
}
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
}
public final void notifyDataSetChanged() {
mObservable.notifyChanged();
}
public final void notifyItemChanged(int position) {
mObservable.notifyItemRangeChanged(position, 1);
}
public final void notifyItemChanged(int position, Object payload) {
mObservable.notifyItemRangeChanged(position, 1, payload);
}
public final void notifyItemRangeChanged(int positionStart, int
itemCount) {
mObservable.notifyItemRangeChanged(positionStart, itemCount);
}
public final void notifyItemRangeChanged(int positionStart, int
itemCount, Object payload) {
mObservable.notifyItemRangeChanged(positionStart, itemCount, payload);
}
public final void notifyItemInserted(int position) {
mObservable.notifyItemRangeInserted(position, 1);
}
public final void notifyItemMoved(int fromPosition, int toPosition) {
mObservable.notifyItemMoved(fromPosition, toPosition);
}
public final void notifyItemRangeInserted(int positionStart, int
itemCount) {
mObservable.notifyItemRangeInserted(positionStart, itemCount);
}
public final void notifyItemRemoved(int position) {
mObservable.notifyItemRangeRemoved(position, 1);
}
public final void notifyItemRangeRemoved(int positionStart, int
itemCount) {
mObservable.notifyItemRangeRemoved(positionStart, itemCount);
}
}“`
俺们得以看来notifyDataSetChange()中调用了mObservable.notifyChange()。继续看艾达pterDataObservable类

static class AdapterDataObservable extends Observable<AdapterDataObserver> {
public boolean hasObservers() {
return !mObservers.isEmpty();
}
public void notifyChanged() {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
public void notifyItemRangeChanged(int positionStart, int itemCount) {
notifyItemRangeChanged(positionStart, itemCount, null);
}
public void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload);
}
}
public void notifyItemRangeInserted(int positionStart, int itemCount) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeInserted(positionStart, itemCount);
}
}
public void notifyItemRangeRemoved(int positionStart, int itemCount) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeRemoved(positionStart, itemCount);
}
}
public void notifyItemMoved(int fromPosition, int toPosition) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeMoved(fromPosition, toPosition, 1);
}
}
}```
Observable是一个被观察者:

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();
    }
    }
    }“`
    AdapterDataObserver 的派生类RecyclerViewDataObserver:
    mObserver是RecycleView的一个变量

private final RecyclerViewDataObserver mObserver = new RecyclerViewDataObserver();```

private class RecyclerViewDataObserver extends AdapterDataObserver {
@Override
public void onChanged() {
assertNotInLayoutOrScroll(null);
if (mAdapter.hasStableIds()) {
// TODO Determine what actually changed.
// This is more important to implement now since this callback will
disable all
// animations because we cannot rely on positions.
mState.mStructureChanged = true;
setDataSetChangedAfterLayout();
} else {
mState.mStructureChanged = true;
setDataSetChangedAfterLayout();
}
if (!mAdapterHelper.hasPendingUpdates()) {
requestLayout();
}
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object
payload) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeChanged(positionStart, itemCount,
payload)) {
triggerUpdateProcessor();
}
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeInserted(positionStart, itemCount)) {
triggerUpdateProcessor();
}
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeRemoved(positionStart, itemCount)) {
triggerUpdateProcessor();
}
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int
itemCount) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeMoved(fromPosition, toPosition,
itemCount)) {
triggerUpdateProcessor();
}
}
void triggerUpdateProcessor() {
if (mPostUpdatesOnAnimation && mHasFixedSize && mIsAttached) {
ViewCompat.postOnAnimation(RecyclerView.this,
mUpdateChildViewsRunnable);
} else {
mAdapterUpdateDuringMeasure = true;
requestLayout();
}
}
}“`
RecycleView的setAdapter方法,可以看出里边调用了unregisterAdapterDataObserver及register艾达(Ada)pterDataObserver方法举办撤除注册及注册。

public void setAdapter(Adapter adapter) {
 // bail out if layout is frozen
 setLayoutFrozen(false);
 setAdapterInternal(adapter, false, true);
 requestLayout();
 }
private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious,
 boolean removeAndRecycleViews) {
 if (mAdapter != null) {
 mAdapter.unregisterAdapterDataObserver(mObserver);
 mAdapter.onDetachedFromRecyclerView(this);
 }
 if (!compatibleWithPrevious || removeAndRecycleViews) {
 // end all running animations
 if (mItemAnimator != null) {
 mItemAnimator.endAnimations();
 }
 // Since animations are ended, mLayout.children should be equal to
 // recyclerView.children. This may not be true if item animator's end does not work as
 // expected. (e.g. not release children instantly). It is safer to use mLayout's child
 // count.
 if (mLayout != null) {
 mLayout.removeAndRecycleAllViews(mRecycler);
 mLayout.removeAndRecycleScrapInt(mRecycler);
 }
 // we should clear it here before adapters are swapped to ensure correct callbacks.
 mRecycler.clear();
 }
 mAdapterHelper.reset();
 final Adapter oldAdapter = mAdapter;
 mAdapter = adapter;
 if (adapter != null) {
 adapter.registerAdapterDataObserver(mObserver);
 adapter.onAttachedToRecyclerView(this);
 }
 if (mLayout != null) {
 mLayout.onAdapterChanged(oldAdapter, mAdapter);
 }
 mRecycler.onAdapterChanged(oldAdapter, mAdapter, compatibleWithPrevious);
 mState.mStructureChanged = true;
 markKnownViewsInvalid();
 }```
到这里我们知道,setAdapter()方法会进行观察者的注册,当RecycleView的数据发送变化的时,调用了Adapter的notifyDataSetChange(),这个函数又会调用 AdapterDataObservable的notifyChanged();该函数会遍历所有的观察者的onChange函数,在 RecyclerViewDataObserver的onChange()函数中会获取Adapter中数据集的新数量,然后调用RecycleView的requestLayout()方法重新进行布局,更新用户的界面。这就是一个观察者模式!
出处:http://huangjunbin.com/page/2/

相关文章