最近看到安卓中一个功能的实现源码中用到了observer模式,就顺便总结一下。
1、导入:如果一个对象的某种属性变化,想要让所有关注他的人感受到这种变化,这个时候可以考虑使用观察者模式,从这句话就可以读出,观察者模式的几个主要组成,主角(subject),粉丝(observer)。
2、粉丝获取这种变化的方式有两种,第一种,自己去主动获取,第二种,让主角把内容拿过去一下,也就是拉和推两种方式。
3、实现,这里采用java里边的的observer和observable两个类实现一下,observable就是主角,observer就是粉丝,以下实现以时间变化为例,时间的变化去通知学生。
import java.util.Observable; public class TimeSubject extends Observable{ private String curTime; public String getCurTime() { return curTime; } public void setCurTime(String curTime) { this.curTime = curTime; //通知观察者,必须首先调用setChanged this.setChanged(); //主动通知观察者,第一种是推方法 this.notifyObservers(curTime); //第二种是拉方式 //this.notifyObservers(); } }
当时间有变化,去通知观察者学生,必须首先用setChanged标记,再调用notifyObservers通知观察者,
import java.util.Observable; import java.util.Observer; public class StudentObserver implements Observer{ private String observerName; public String getObserverName() { return observerName; } public void setObserverName(String observerName) { this.observerName = observerName; } public void update(Observable arg0, Object arg1) { //推的方式 System.out.println(observerName +"获取到时间"+arg1); //拉的模式,直接去subject中去拉内容 //System.out.println(((TimeSubject)arg0).getCurTime()); } }
观察者在个子的update函数中实现各自的操作处理
public class Test { public static void main(String[] args) { final TimeSubject timeSubject = new TimeSubject(); StudentObserver observer = new StudentObserver(); observer.setObserverName("小明"); StudentObserver observer2 = new StudentObserver(); observer2.setObserverName("小张"); timeSubject.addObserver(observer); timeSubject.addObserver(observer2); new Thread(){ public void run() { while(true){ timeSubject.setCurTime(new Date().toGMTString()); try { sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }.start(); } }
主函数进行测试,将观察者和主角联系起来分四步走:
(1)创建主角对象
(2)创建观察者们
(3)将观察者们attach到主角身上
(4)调用主角的方法(方法中实现notifyObservers)通知各个观察者
于是乎,所有的观察者们都得到了主角的消息