Android——观察者模式

最近几天闲着没事  问老大学点什么  老大说让我看看那个观察者模式吧  我就看了一下午  写了一个小Demo,我们首先想到的肯定是单例模式 观察者模式也是一种常用的设计模式 我就不废话了 。大家首先可以去了解一下观察者模式,我就说简单一点:定义对象间的一种一个对多的依赖关系,当这个”一“发生改变的时候与之对应的”多“会得到通知并自动更新

    开发中我们可能经常遇到一个问题,某一个数据改变,那么对应的UI显示也要改变,那么这样改变你是希望手动的去请求接口,还是想后台主动通知你数据改变了,我想大多数人肯定是不想再去请求接口了,肯定是希望当一次”老大“ 让数据主动通知你,这就是观察者的好处,这样说有点牵强,其中的意思大家理解就好,我们接着看观察者模式的要素:

1.Subject(被观察者) 我们这里可以理解成某个数据源

2.Observer(观察者) 这里我们可以理解为一个通讯的”电话“

当数据源发生改变的时候,我们通过”电话“去通知相应的UI去改变显示


1.被观察者(数据源) 

/**
 * 被观察者 简单理解一点就是(数据源) 主要功能就是添加和删除观察者以及通知观察者改变数据
 * 
 * @author lvyanbo
 * 
 */
public interface MSubject {
// 添加观察者
public void add(MyWatcher watcher);

// 撤销观察者
public void remove(MyWatcher watcher);

// 通知注册的观察者进行数据更新(如更新UI)
public void notifyObserver(String type);

}

被观察者实现类



/**
 *  添加观察者和删除观察者以及更新UI 被观察者实现类 被观察者实现类
 * 
 * @author lvyanbo
 * 
 */
public class MyWatched implements MSubject {
private List<MyWatcher> watchers;
private static volatile MyWatched myWatched;
public MyWatched() {
watchers = new ArrayList<MyWatcher>();
}

// 线程安全的单例
public synchronized static MyWatched getInstance() {
if (myWatched == null) {
myWatched = new MyWatched();
}
return myWatched;
}
// 添加观察者
@Override
public void add(MyWatcher watcher) {
synchronized (watchers) {
if (watchers.contains(watcher)) {
return;
}
watchers.add(watcher);
}
}
// 注销观察者
@Override
public void remove(MyWatcher watcher) {
synchronized (watchers) {
int index = watchers.indexOf(watcher);
if (index >= 0) {
watchers.remove(watcher);
}
}
}
// 通知观察者
@Override
public void notifyObserver(String type) {
if (!TextUtils.isEmpty(type) && watchers.size() > 0 && watchers != null) {
for (MyWatcher watcher : watchers) {
watcher.UpdateUI(type);
}
}
}
}

上面我就不详细解释了,如果大家认真去看观察者模式 这些代码应该是没问题的

2.观察者

/**
 * 观察者(观察数据源的变化通知UI进行相应的修改) 通过UpdateUI改变UI
 * 
 * @author lvyanbo
 * 
 */
public interface MObserver {
public  void UpdateUI(String type);
}

观察者实现类

/**
 * 观察者实现类
 * 
 * @author lvyanbo
 * 
 */
public abstract  class MyWatcher implements MObserver {
public static Handler handler;
public abstract void changeUI(String eventType);
public MyWatcher() {
handler = new Handler(Looper.getMainLooper());
}
// 用Handler post方法主要是做一下适配 
@Override
public void UpdateUI(String type) {
handler.post(new MyRunable(type));
}
class MyRunable implements Runnable {
private String type;
public MyRunable(String type) {
this.type = type;
}
@Override
public void run() {
MyWatcher.this.changeUI(type);
}
}
}

我这里就说一句那个handler.post 我只是做了一个兼容,不管是在主线程还是子线程中改变数据源我都可以通过post去进行更新数据

其他的不多说了

3.MainActivity



public class MainActivity extends ActionBarActivity {
// 观察者
private MMM myWatcher;
private List<String> liStrings;
// 被观察者
private MyWatched mmMyWatched;
private Timer timer;


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 初始化被观察者
mmMyWatched = MyWatched.getInstance();
PreferencesUtil.putInt(MainActivity.this, "mm", 20);
liStrings = new ArrayList<String>();
liStrings.add(Constance.STATUS_ONE);
int index = liStrings.size();
timer = new Timer();
// 注册观察者
for (int i = 0; i < index; i++) {
myWatcher = new MMM();
mmMyWatched.add(myWatcher);
}
TimerTask timerTask = new TimerTask() {


@Override
public void run() {
if (PreferencesUtil.getInt(MainActivity.this, "mm", 0) == 20) {
// 被观察者发出数据变更的通知
mmMyWatched.notifyObserver(Constance.STATUS_ONE);
}
}
};
timer.schedule(timerTask, 5000);
}


// 实现观察者
class MMM extends MyWatcher {
// 回调到这里去判断是哪个
@Override
public void changeUI(String eventType) {
if (eventType.equals(Constance.STATUS_ONE)) {
Toast.makeText(MainActivity.this, "观察者发现了数据变化", 2000).show();
}
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (timer != null) {
timer.cancel();
timer = null;
}
if (myWatcher != null) {
mmMyWatched.remove(myWatcher);
}
}
}


PreferencesUtil是我自己定义的一个share类保存数据的 我这里就是做了一个测试,过5s我去发一个通知然后去接受这个通知弹出一个Toast这里我给他传了一个type,我们可以把这个type理解成代码中各种接口的一个标示,数据更新我的知道哪些接口更新哪些不用更新 所以我用了这么一个type。这个观察者模式有时候理解起来有那么一点点绕 ,大家一定多动脑想想,这个模式确实好用,现在我的项目中就用了这个模式 

总结:

总之这个观察者模式要仔细琢磨一下,我们可以这样理解,数据源改变的时候,我们主动去发送一个通知,让所有依赖这个数据源的UI都去进行更新就行了 给大家一个Demo的私密    链接:http://pan.baidu.com/s/1c1tPUbI 密码:r5qz 



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值