观察者(Observer)模式是对象的行为型模式,又叫做发表-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-收听者(Source/Listener)模式或从属者(Dependents)模式。
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个对象。这个主题对象在状态发生状态变化时,会通知所有观察者对象,使它们能够自动更新自己。
Subject:被观察者,它把所有观察者对象引用保存到一个集合中,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以添加和删除观察者对象。
Observer:抽象观察者,为所有的具体观察者定义一个接口,得到主题的更新时通知自己。
Observable JDK源码:
1 public class Observable { 2 private boolean changed = false; 3 private Vector obs; 4 5 //创建被观察者时就创建一个它持有的观察者列表,注意,这个列表是需要同步的。 6 public Observable() { 7 obs = new Vector(); 8 } 9 10 /** 11 * 添加观察者到观察者列表中去 12 */ 13 public synchronized void addObserver(Observer o) { 14 if (o == null) 15 throw new NullPointerException(); 16 if (!obs.contains(o)) { 17 obs.addElement(o); 18 } 19 } 20 21 /** 22 * 删除一个观察者 23 */ 24 public synchronized void deleteObserver(Observer o) { 25 obs.removeElement(o); 26 } 27 28 /** 29 * 通知操作,即被观察者发生变化,通知对应的观察者进行事先设定的操作,不传参数的通知方法 30 */ 31 public void notifyObservers() { 32 notifyObservers(null); 33 } 34 35 /** 36 * 与上面的那个通知方法不同的是,这个方法接受一个参数,这个参数一直传到观察者里,以供观察者使用 37 */ 38 public void notifyObservers(Object arg) { 39 40 Object[] arrLocal; 41 42 synchronized (this) { 43 if (!changed) 44 return; 45 arrLocal = obs.toArray(); 46 clearChanged(); 47 } 48 49 for (int i = arrLocal.length-1; i>=0; i--) 50 ((Observer)arrLocal[i]).update(this, arg); 51 } 52 }
Observer JDK源码:
1 public interface Observer { 2 /** 3 * This method is called whenever the observed object is changed. An 4 * application calls an <tt>Observable</tt> object's 5 * <code>notifyObservers</code> method to have all the object's 6 * observers notified of the change. 7 * 8 * @param o the observable object. 9 * @param arg an argument passed to the <code>notifyObservers</code> 10 * method. 11 */ 12 void update(Observable o, Object arg); 13 }
Demo:
1 import java.util.Observable; 2 import java.util.Observer; 3 4 public class JMSObserver implements Observer{ 5 6 public void update(Observable o, Object arg) { 7 System.out.println("发送消息给jms服务器的观察者已经被执行"); 8 } 9 }
1 import java.util.Observable; 2 import java.util.Observer; 3 4 public class MailObserver implements Observer{ 5 6 /** 7 * 这个类取名为MailObserver,顾名思义,她是一个用来发送邮件的观察者 8 */ 9 public void update(Observable o, Object arg) { 10 if(o instanceof Subject){ 11 int flag = ((Subject)o).getFlag(); 12 if(flag == 1){ 13 System.out.println("我观察的人在" + arg.toString() + " , 发送邮件的观察者已经被执行。"); 14 } 15 } 16 } 17 }
1 import java.util.Observable; 2 3 public class Subject extends Observable{ 4 5 private int flag; 6 7 public int getFlag() { 8 return flag; 9 } 10 11 public void setFlag(int flag) { 12 this.flag = flag; 13 } 14 15 /** 16 * 业务方法,一旦执行某个操作,则通知观察者 17 */ 18 public void doBusiness(){ 19 if (true) { 20 //必须加上setChanged(),否则不会通知观察者 21 super.setChanged(); 22 } 23 notifyObservers("吃饭"); 24 } 25 26 }
1 public static void main(String [] args) { 2 //创建一个被观察者 3 Subject subject = new Subject(); 4 subject.setFlag(1); 5 //创建两个观察者 6 Observer mailObserver = new MailObserver(); 7 Observer jmsObserver = new JMSObserver(); 8 9 //把两个观察者加到被观察者列表中 10 subject.addObserver(mailObserver); 11 subject.addObserver(jmsObserver); 12 13 //执行业务操作 14 subject.doBusiness(); 15 }
打印结果:
发送消息给jms服务器的观察者已经被执行
我观察的人在吃饭 , 发送邮件的观察者已经被执行。