设计模式17——Observer设计模式

Observer观察者设计模式用于将对象的变化通知给感兴趣的用户。在Observer模式中的角色为主题(subject)与观察者(observer),观察者订阅它感兴趣的主题,一个主题能够被多个观 察者订阅,当主题的状态发生变化时,它必须通知(notify)全部订阅它的观察者,观察者检视主题的状态变化,并做出对应的动做,因此Observer模式也称之为Publish-Subscribe模式。 Observer观察者设计模式结构以下: java

观察者模式顺序图以下: 编程


以一个电子商务网站商品价格变时通知订阅用户为例,演示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 List<Observer> observers = new ArrayList<Observer>();
    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):为主题添加观察者。 this

b.publicvoid deleteObserver(Observer o):删除某个观察者。 spa

c.publicvoid deleteObservers():删除主题上的全部观察者。 设计

d.publicboolean hasChanged():测试主题是否改变。 code

e.protectedvoid setChanged():标记该主题对象已经改变。 server

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中观察者模式的应用:

java.util.Observer
java.util.Observable
java.util.EventListener
javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener