标签:
传统的MVC相信大家都用的,特别是做web开发的人员(server端)。
一般数据的请求,变更都会请Controller控制,然后找到对应的Model,这是一般的MVC。然后Model一旦有变化了,能自动反馈到View上,这就是用了观察者模式了(一个对象发生变化,所有依赖它的对象都得到通知并被自动更新)。(然而大多数MVC,比方说表现层的Struts2貌似就没有这样实现。。为啥,它的那个设计机制或者web的bs模型决定了它实现不了。。至少我当时用的时候就发现是这么个样子咯)
先看看原作者介绍的Android中的一种实现,实际上,作者也是借用的Java,JDK的API,然后结合Android的组件搭建了一个简单的框架。
文章最后,我讲讲Observer的本质。
本文转载整理自:http://blog.csdn.net/feiduclear_up/article/details/42167487
观察者模式“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象都将得到通知,并自动更新”,可以理解成多个观察者向一个被观察者订阅消息,当被观察者发生改变时通知相应的观察者去作自己的事情。Android 中的观察者 实现Observer接口,被观察者继承Observable类。使用步骤如下:
1.观察者DataWatcher 实现Observer 接口。
2.被观察者DataChange继承Observable 类。
3.观察者DataWatcher 向被观察者 DataChange 订阅事件(将观察者DataWatcher添加到被观察者DataChange里面去)。
4.被观察者DataChange数据有改变,通知观察者DataWathcer相应的数据有改变,请作出相应的操作。
5.观察者DataWather 向被观察者 DataChange取消订阅事件(将观察者DataWatcher从被观察者DataChange中移除)。
代码实现如下:
1.观察者类
package com.example.observer; import java.util.Observable; import java.util.Observer; /** * TODO<请描述这个类是干什么的> * * @author xjp * @data: 2014年12月26日 上午9:29:56 * @version: V1.0 */ public abstract class DataWatcher implements Observer { @Override public void update(Observable observable, Object data) { } }
2.被观察者类
package com.example.observer; import java.util.Observable; /** * TODO<请描述这个类是干什么的> * * @author xjp * @data: 2014年12月26日 上午9:30:21 * @version: V1.0 */ public class DataChange extends Observable { private static DataChange instance = null; public static DataChange getInstance() { if (null == instance) { instance = new DataChange(); } return instance; } public void notifyDataChange(Data data) { //被观察者怎么通知观察者数据有改变了呢??这里的两个方法是关键。 setChanged(); notifyObservers(data); } }
3.操作类
package com.example.observer; import java.util.Observable; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; public class MainActivity extends Activity { private DataWatcher watcher = new DataWatcher() { @Override public void update(Observable observable, Object data) { super.update(observable, data); //观察者接受到被观察者的通知,来更新自己的数据操作。 Data mData = (Data)data; Log.i("Test", "mData---->>"+mData.getDataChange()); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //模拟被观察者数据改变,更新数据。 Data mData = new Data(); mData.setDataChange(0); DataChange.getInstance().notifyDataChange(mData); } @Override protected void onResume() { super.onResume(); //观察者往被观察者中添加订阅事件。 DataChange.getInstance().addObserver(watcher); } @Override protected void onPause() { super.onPause(); //观察者从被观察者队列中移除 DataChange.getInstance().deleteObserver(watcher); } }
4.数据类:
package com.example.observer; /** * TODO<请描述这个类是干什么的> * * @author xjp * @data: 2014年12月26日 上午9:33:33 * @version: V1.0 */ public class Data { private int dataChange; public Data() { } public int getDataChange() { return dataChange; } public void setDataChange(int dataChange) { this.dataChange = dataChange; } }
注意:我主要是实现android 中观察者模式代码的一个框架,具体怎么写代码还得看实际的业务。其实编程最主要的思想就是框架的实现了。
我的补充:
上面也看到了,观察者订阅了被观察者,却不是每时每刻的监听&关注被观察者,要是这样的话,不仅难以实现,而且,对系统资源的耗费也很大(观察者干脆不用做事儿了,天天就看着被观察者就好了呵呵)。实际上观察者模式的一个重点就是,观察者虽然是主动观察订阅被观察者,然后,发生通知却是被观察者拿起了主动权。(似乎一切又平衡了)
简单的例子:
好比说,我的联想电脑坏了,我报修了,然后上海这边儿的售后也获悉了这个事情,说暂时没有工程师可以安排上门,人手最近缺的紧,那我不可能总是盯着他们的人手,天天打电话过去问吧?实际上大家都知道,是他们有了人,然后才会来问我预约时间上门维修的。(被观察者是联想售后服务,然后却拥有主动通知权)
大致上我就总结了上面作者的核心观点。
然而作者的观点还有明显的一点不足: 观察者可能有多个,它的例子并没有体现。(被观察者可能通知多个观察者变化情况),实际上,观察者模式反应的就是一对多的关系。一个对象发生了改变,然后依赖它的多个对象都会获得通知并自动更新。
既然晓得了原理,我们抛开Java和Android组件,来说个更普遍的(自己动手画图实现)
好吧,我突然发现StartUML自己也有实现,你先看看它自动生成的图:
看到啦,这是一种画法(+subject的意思是,观察者订阅主题,这里是实线箭头,表示直接联系的意思。Subject这里就是被观察者)
如果要我画的话,我根本不这么画,我多用接口:(在他的图上我改改)
观察者,可以是组织机构,也可以是个人(所以我画了Observer0,Observer1等等)
观察者还是依赖被观察者的变化的,而依赖应该是从抽象层面就开始的,所以画在接口上。
然而接口一般不直接用,虽然面向接口编程,然而接口强调的是功能,表现在方法上,所以一般都会给他一个默认类(这一点很多源码已经这么做了,android也好,Struts也好,spring也好,都有这样做),并把观察者集合放在其中。
好了罗里吧嗦的,又说了半会儿。
我能力有限,就说这么多,不贪多、不贪多。
merlin
10/4/2015
标签:
原文地址:http://my.oschina.net/wizardmerlin/blog/513420