自定义滚轮系列---设计模式之观察者模式

本文介绍了观察者模式在Android开发中的应用,特别是在自定义滚轮组件WheelView中的实现。文章详细阐述了观察者模式的基本概念、角色以及适用场景,并结合ListView和WheelView的Adapter,解析了如何使用观察者模式实现数据更新的自动同步。
摘要由CSDN通过智能技术生成

对于Adapter我相信大家都很熟悉,在使用ListView或者是GridView控件时,我们经常会用到Adapter,我们通常的做法是自定义一个Adapter继承自BaseAdapter,然后调用ListView的setAdapter()方法,将数据与ListView绑定起来。但是我们对于Adapter又了解多少呢,我们是否知道它的实现原理呢。

今天我们要说的是Adapter中的观察者模式,如果你想详细了解观察者模式,你可以参考这篇文章 设计模式学习笔记-观察者模式

一、关于观察者模式主要有以下几点:

1、定义:观察者模式(Observer Pattern)也叫发布订阅模式(Publish/subscribe),它是一个在项目中经常使用的模式,其定义如下:

Define a one-to-many dependency between objects so that when one object changes state,all its dependents are notified and updated automatically(定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖与他的对象都会得到通知并被自动更新)

2、观察者模式的通用类图:

3、观察者模式的几个角色名称:

·Subject被观察者:定义被观察者必须实现的职责,他必须能够动态的增加,取消观察者。他一般是抽象类或者实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知被观察者。

·Observer被观察者:观察者接受到消息之后,即进行update(更新方法)操作,对接收到的信息进行处理。

·ConcreteSubject具体的被观察者:定义被观察者自己业务逻辑,同时定义对哪些事件进行通知。

·ConcreteObserver具体的观察者:每个观察者的在接收到消息后的处理反应是不同的,各个反应者有自己的处理逻辑。

 4、观察者模式的使用场景:

1、对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变

2、对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节

、观察者模式在ListView和WheelView中的应用

1、我们先来看一下类图:

2、关于上面类图,我们可以发现:

[1]DataSetObserve是观察者

[2]DataSetObservable是被观察者,即角色,它持有很多个观察者对象

[3]DataSetObservable持有DataSetObserve对象

[4]而BaseAdapter中又持有DataSetObservable对象,所以相当于,BaseAdapter也持有DataSetObserve对象
3、接着我们再看ListView中的setAdapter()方法

ListView的setAdapter()方法的源代码我就不贴出来了,我们可以在setAdapter()方法中可以看到这样一句mAdapter.registerDataSetObserver(mDataSetObserver);在BaseAdapter类中我们可以看到registerDataSetObserver()方法的具体实现为:

public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable .registerObserver(observer);
}
而该方法又是调用了DataSetObservable中的registerObserve(observer)方法,在DataSetObservable中我们可以看到registerObserve()方法的具体实现为:
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);
}
}
所以通过Listview的setAdapter方法,我们就将一个DataSetObserve添加到了Adapter的DataSetObservable中,即给adapter添加了一个观察者
4、下面我们来看一下adapter中notifyDataSetChanged方法的实现过程
当数据有变动时,我们经常通过notifyDataSetChanged方法来刷新界面,在BaseAdapter类中,我们可以看到notifyDataSetChanged方法的具体实现为:
public void notifyDataSetChanged() {
mDataSetObservable .notifyChanged();
}
我们又可以看到notifyDataSetChanged()方法中仅仅是调用了DataSetObservable中的notifyChanged()方法,接下来我们再来看notifyChanged方法的具体实现:
DataSetObservable类中
public void notifyChanged() {
synchronized ( mObservers ) {
// since onChanged() is implemented by the app, it could do anything, including
// removing itself from {@link mObservers} - and that could cause problems if
// an iterator is used on the ArrayList {@link mObservers}.
// to avoid such problems, just march thru the list in the reverse order.
for ( int i = mObservers .size() - 1; i >= 0; i--) {
mObservers .get(i).onChanged();
}
}
}
我们可以看到,它的实现也很简单,就是通过循环的方式,依次调用每个观察者(DataSetObserver)的onChanged()方法;我们在ListView的setAdapter方法中调用的mAdapter.registerDataSetObserver(mDataSetObserver);方法中的参数mDataSetobserver是一个 AdapterDataSetObserver 类型的类,而它又是继承自DataSetObserver类的, 下面我们可以看到AdapterDataSetObserver 类的源码实现:
class AdapterDataSetObserver extends DataSetObserver
{
private Parcelable mInstanceState = null;
AdapterDataSetObserver() {
}
public void onChanged() { mDataChanged = true;
mOldItemCount = mItemCount;
mItemCount = getAdapter().getCount();
if ((getAdapter().hasStableIds()) && (mInstanceState != null) && (mOldItemCount == 0) && (mItemCount > 0))
{
onRestoreInstanceState(mInstanceState);
mInstanceState = null;
} else {
rememberSyncState();
}
checkFocus();
requestLayout();
}
//...省略不必要代码
}
在该类中我们可以看到调用了requestLayout()方法,该方法就是用来进行页面刷新的
自定义滚轮中AbstractWheelAdapter的实现方式与Android中BaseAdapter的实现方式类似,它也使用了观察者模式,只是他没有使用一个单独的被观察者角色(类似于Android源码中的DataSetObservable类),而是让AbstractWheelAdapter直接持有观察者对象,即AbstractWheelAdapter本身就是一个被观察者,它里面有一个datasetObservers变量用来存储观察者对象。
Android源码的实现方式为,adapter持有被观察者,而被观察者再持有观察者对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值