Design Pattern(設計模式- 行爲模式)-------Observer(觀察者)

Observer模式也叫觀察者模式,是由GoF提出的23種軟件設計模式的一種。Observer模式是行爲模式之一,它的作用是當一個對象的狀態發生變化時,能夠自動通知其他關聯對象,自動刷新對象狀態

應用場景

- 偵聽事件驅動程序中的外部事件
- 偵聽/監視某個對象的狀態變化
- 發佈者/訂閱者(publisher/subscriber)模型中,當一個外部事件(新的產品, 消息的出現等等)被觸發時,通知郵件列表中的訂閱者

結構模型

img

JDK對觀察者模式的實現.Observer觀察者與Observable被觀察者 


public class Client {

    public static void main(String[] args) {
        NewsPublisher publisher = new NewsPublisher();
        //添加觀察者對象
        publisher.addObserver(new SubscriberObserver());
        publisher.addObserver(new ManagerObserver());
        
        //發佈新聞,觸發通知事件
        publisher.publishNews("Hello news", "news body");
    }
}

 

//被觀察者

class NewsPublisher extends Observable {
    public void publishNews(String newsTitle, String newsBody) {
        News news = new News(newsTitle, newsBody);
        setChanged();//標明對象的狀態已發生變化
        System.out.println("News published:" + newsTitle);
        this.notifyObservers(news);//通知各Observer,併發送一個名爲news對象的消息   
        //other process ... such as save news to database
    }
}

 

 

//觀察者

class SubscriberObserver implements Observer {
    
    public void update(Observable observee, Object param) {
        if (param instanceof News) {
            mail2Subscriber((News)param);
        }
    }
    
    private void mail2Subscriber(News news) {
        System.out.println("Mail to subscriber. A news published with title:" + news.getTitle());
    }
}

 

//觀察者

class ManagerObserver implements Observer {
    
    public void update(Observable observee, Object param) {
        if (param instanceof News) {
            mail2Manager((News)param);
        }
    }
    
    private void mail2Manager(News news) {
        System.out.println("Mail to Manager. A news published with title:" + news.getTitle());
    }
}

一般優先選擇jdk已經提供的方式.當然我們也可以自己實現.在此之前不妨看看jdk 關於observer與observable的代碼實現.

 

JDK中的Observer接口和Observable類實現

 

public interface Observer { 

//這個方法被每當觀測目標被改變了,讓被觀察者調用 

void update(Observable o, Object arg); 

 

 

public class Observable {  

    private boolean changed = false;  

    //觀察者的集合  

    private Vector obs;  

     

    /** Construct an Observable with zero Observers. */  

  

    public Observable() {  

     obs = new Vector();  

    }  

  

      

    public synchronized void addObserver(Observer o) {  

        if (o == null)  

            throw new NullPointerException();  

     if (!obs.contains(o)) {  

          obs.addElement(o);  

     }  

    }  

  

    public synchronized void deleteObserver(Observer o) {  

        obs.removeElement(o);  

    }  

  

    public void notifyObservers() {  

     notifyObservers(null);  

    }  

  

    //通知所有訂閱此主題的觀察者對象  

    public void notifyObservers(Object arg) {  

        Object[] arrLocal;  

     //同步代碼塊  

     synchronized (this) {  

          //若主題沒有改變,返回  

         if (!changed)  

                return;  

             arrLocal = obs.toArray();  

             clearChanged();  

         }  

  

         for (int i = arrLocal.length-1; i>=0; i--)  

             //通知觀察者,調用觀察者的update()方法  

              ((Observer)arrLocal[i]).update(this, arg);  

    }  

  

    //清空所有觀察此主題的觀察者  

    public synchronized void deleteObservers() {  

     obs.removeAllElements();  

    }  

  

    //主題改變  

    protected synchronized void setChanged() {  

     changed = true;  

    }  

  

   //清除改變  

    protected synchronized void clearChanged() {  

     changed = false;  

    }  

  

   //判斷主題是否改變  

    public synchronized boolean hasChanged() {  

    R eturn changed;  

    }  

  

   //返回觀察者的數量  

    public synchronized int countObservers() {  

     Return obs.size();  

    }  

}  

 

總結:觀察者模式實現相對簡單,但是在一些典型應用中卻很實用.複雜環境可以結合其他的模式 來完成整個模塊或者系統的設計.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章