Observer观察者设计模式用于将对象的变化通知给感兴趣的用户。在Observer模式中的角色为主题(subject)与观察者(observer),观察者订阅它感兴趣的主题,一个主题可以被多个观 察者订阅,当主题的状态发生变化时,它必须通知(notify)所有订阅它的观察者,观察者检视主题的状态变化,并作出对应的动作,所以Observer模式也称之为Publish-Subscribe模式。 Observer观察者设计模式结构如下:
观察者模式顺序图如下:
以一个电子商务网站商品价格变时通知订阅用户为例,演示Observer观察者设计模式,代码如下:
//主题interface Subject{ //注册观察者 public void registerObserver(Observer o); //注销观察者 public void unregisterObserver(Observer o); //通知观察者 public void notifyObservers();}//观察者interface Observer{ //更新价格信息 public void update(float price);}//商品class Product implements Subject{ //观察者列表 private Listobservers = new ArrayList (); private float price; public void registerObserver(Observer o){ observers.add(o); } public void unregisterObserver(Observer o){ observers.remove(o); } public void notifyObservers(){ for(Observer observer : observers){ //主题向观察者推送更新数据 observer.update(price); } } public void priceChanged(){ notifyObservers(); } public void setPrice(float price){ this.price = price; priceChanged(); }}//订阅者class Subscriber implements Observer{ private float currentPrice; //观察者引用主题 private Subject product; public Subscriber(Subject product){ this.product = product; //主题注册观察者 product.registerObserver(this); } public void update(float price){ this. currentPrice = price; System.out.println(“Current price change to:” + currentPrice); }}public class ObserverDemo{ public static void main(String[] args){ Subject product = new Product(); Subscriber subscriber = new Subscriber(product); product.setPrice(10.98); product.setPrice(998.15); }}
在java的java.util中内置了Observer观察者设计模式,其中:
(1).java.util.Observable是主题类,所有继承了该类的类是事件发生的主题,也是被观察的对象。java.util.Observable的常用方法有:
a.public void addObserver(Observer o):为主题添加观察者。
b.publicvoid deleteObserver(Observer o):删除某个观察者。
c.publicvoid deleteObservers():删除主题上的所有观察者。
d.publicboolean hasChanged():测试主题是否改变。
e.protectedvoid setChanged():标记该主题对象已经改变。
f.publicvoid notifyObservers():通知所有观察者对象已经已经改变。
(2).java.util.Observer接口是观察者,所有实现了该接口的类都是主题事件的观察者,该接口只有一个方法需要实现:
publicvoid update(Observable o, Object arg):通知观察者更新已经改变的主题。
使用JDK内置的Observer观察者设计模式,演示电子商务网站商品价格的例子如下:
//商品class Product extends Observable{ private float price; public void priceChanged(){ //设置变化点 setChanged(); //通知观察者 notifyObservers(); } public void setPrice(float price){ this.price = price; priceChanged(); } public float getPrice(){ return price; }}//订阅者class Subscriber implements Observer{ private float currentPrice; //观察者引用主题 private Observable observable; public Subscriber(Observable observable){ this. observable = observable; //主题注册观察者 observable.addObserver(this); } public void update(Observable observable, Object arg){ if(observable instanceof Product){ Product product = (Product) observable; this. currentPrice = product.getPrice(); System.out.println(“Current price change to:” + currentPrice); } }}public class ObserverDemo{ public static void main(String[] args){ Observable product = new Product(); Subscriber subscriber = new Subscriber(product); product.setPrice(10.98); product.setPrice(998.15); }}
Observer观察者设计模式在界面编程中应用广泛,一个button往往会注册一个onclickListener,里面有onclickAction方法对点击进行响应,此时button充当的就是主题,而onclickListener就是观察者,而onclickAction就对应着观察者中对事件进行响应的update方法。
JDK中观察者模式的应用: