1. 程式人生 > >設計模式之觀察者模式——利用java中提供的觀察者實現

設計模式之觀察者模式——利用java中提供的觀察者實現

java實現與自己實現的對比

一、不需要再定義觀察者和目標的介面了,JDK幫忙定義了
二、具體的目標實現裡面不需要再維護觀察者的註冊資訊了,這在Java中的Observable類裡面已經幫忙實現好了。
三、觸發通知的方式有一點變化,要先呼叫setChanged方法,這個是Java未來幫助實現更精確的觸發控制而提供的功能。
四、具體觀察者的實現裡面,update方法其實能同時支援推模型和拉模型,這個是java在定義的時候,就已經考慮進去了。

ConcreteSubject

public class ConcreteSubject extends Observable {
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
        //通知所有股東觀察者
        //注意在通知之前,在用java中Observer模式時候,下面這句不能少
        this.setChanged();
        //然後主動通知,這裡先用推的方式
        this.notifyObservers(content);

        //如果是拉的方式,我們就呼叫
        //this.notifyObservers();//預設把整個subject傳過去了
    }
}

ConcreteObserver

public class ConcreteObserver implements Observer {
    //觀察者名稱的變數
    private String observerName;

    public String getObserverName() {
        return observerName;
    }

    public void setObserverName(String observerName) {
        this.observerName = observerName;
    }

    @Override
    public void update(Observable o, Object arg) {
        //第一種是推的方式
        System.out.println(observerName+"收到了訊息,目標推送過來的是"+arg);
        //第二種是拉的方式
        System.out.println(observerName+"收到了訊息,主動到目標物件中去拉,拉的內容是"+((ConcreteSubject)o).getContent());
    }
}

測試類

public class Client {
    public static void main(String[] args) {
        //建立一個目標,也可以說是被觀察者
        ConcreteSubject subject =new ConcreteSubject();
        //建立觀察者
        ConcreteObserver observer1=new ConcreteObserver();
        observer1.setObserverName("觀察者一號");

        ConcreteObserver observer2=new ConcreteObserver();
        observer2.setObserverName("觀察者二號");

        //註冊觀察者
        subject.addObserver(observer1);
        subject.addObserver(observer2);

        //目標更新content
        subject.setContent("目標內容更新了");
    }
}