設計模式之觀察者模式

觀察者模式(Observer),其含義是定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。這種模式也稱爲發佈-訂閱模式。將一個系統分割一系列相互做用的類有一個常見的反作用:須要維護相關對象間的一致性。咱們不但願爲了維持一致性而使各種緊密耦合,由於這樣下降了它們的可重用性。 觀察者模式的關鍵對象是目標和觀察者,一個目標能夠有任意數目的依賴它的觀察者,一旦目標的狀態發生改變,全部的觀察者都獲得通知。做爲對這個通知的響應,滅個觀察者都將查詢目標以使其狀態與目標的狀態同步。目標是通知的發佈者,它發出通知時並不需知道誰是它的觀察者,能夠有任意數目的觀察者訂閱並接收通知。java

其適用性:git

當一個抽象模型有兩個方面,其中一個方面依賴於另外一方面。將這兩者封裝在獨立的對象中以使它們能夠各自獨立地改變和複用,github

當對一個對象的改變須要同時改變其它對象,而不知道具體有多少對象有待改變,ide

當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之,你不但願這些對象是緊密耦合的。測試

其結構圖:this

                  

每一個subject維護以個Observer的列表,意思是一個目標類能夠被多個觀察者觀察,其能夠綁定或解除一個observer;而observer類必須具備在subject改變時,接收到通知後更新相關信息(如狀態)。實現以下:spa

 package org.designpattern.behavioral.observer;code

import java.util.ArrayList;
import java.util.List;

public  abstract  class Subject {
     protected String state;
     protected List<Observer> observers;
     public  abstract  void attach(Observer observer);
     public  abstract  void detach(Observer observer);
     public  abstract  void notice();

     public String getState() {
         return state;
    }

     public  void setState(String state) {
         this.state = state;
    }
}

  每一個Subject的子類,在通知改變時會通知全部觀察本身的觀察者,具體代碼可參考本博客的github。server

在一個Observer抽象基類裏,會有指定本身要觀察的Subject實例,也就是具備該屬性,經過記錄它的狀態來實現。下面是Observer的一個具體子類,其更新操做是記錄目標的狀態對象

package org.designpattern.behavioral.observer;

public  class ConcreteObserverA  extends Observer {
     public ConcreteObserverA(Subject subject){
         this.subject = subject;
         this.subject.attach( this);
    }
    @Override
     public  void update(Subject subject) {
         // To change body of implemented methods use File | Settings | File Templates.
        this.setState(subject.getState());
    }

} 

  客戶端測試類較爲簡單:

package org.designpattern.behavioral.observer;

public  class Main {
     public  static  void main(String[] args) {
        Subject subject =  new ConcreteSubject();
        Observer obsvrA =  new ConcreteObserverA(subject);
        Observer obsvrB =  new ConcreteObserverB(subject);

        subject.setState("red");
        System.out.println(obsvrA.getState());
        System.out.println(obsvrB.getState());

        subject.notice();
        System.out.println(obsvrA.getState());
        System.out.println(obsvrB.getState());
    }

} 

  第一次觀察者的state都是null,在獲取subject通知後,再次獲取state就是變成了red。

觀察者模式在書中的例子是關於數據顯示問題,這樣根據須要作粗不一樣的顯示圖。觀察者模式和協調者模式同樣都是定義一對多的對象關係,此模式可以使得對象之間進行同步通訊。該模式可與單例模式一塊兒構建一個更改管理其對象,經典的MVC思想很是相似觀察者模式,只是觀察的對象不一樣,其是視圖頁面來觀察數據。

相關文章
相關標籤/搜索