1. 程式人生 > >初探Java設計模式------觀察者模式

初探Java設計模式------觀察者模式

前言

最近剛開始學習RxJava,眾所周知,Rxjava就是擴充套件的觀察者模式,所以想學習Rxjava,先入手瞭解一下觀察者模式是很有必要的。那麼今天就先稍微瞭解一下什麼是觀察者模式。

定義

 觀察者(Observer)模式:是物件的行為模式,也叫做釋出-訂閱(Publish/Subscribe)模式、模型-檢視(Module/View)模式、源-監聽(Source/Listener)模式或者從(Dependents)模式。
 觀察者模式定義了一對多的依賴關係,即讓多個觀察者物件同時監聽同一個主題物件,當這個主題物件的狀態發生改變時,要通知所有的觀察者物件,使他們能夠更新自己。

!
眾大神部落格裡面最多的例子就是天氣預報和小偷警察的例子。拿小偷和警察的例子來說,小偷就是被觀察者,而警察就是觀察者。多個警察在關注小偷的行為,當小偷想偷東西時,即主題物件狀態發生改變時,這個時候很多警察就會上去抓住他,也就是觀察者更新了自己的行為。

UML類圖

Paste_Image.png
我們來解釋一下UML圖中的含義:

Subject
主題,即被觀察者介面,它是一個抽象的介面,包含三個方發,attach()即增加訂閱者,detach()刪除訂閱者,notifyObserver()通知訂閱者;
Observer
觀察者介面,它是一個抽象的介面,其中含有一個update()方發,用來在被觀察者狀態改變的時候進行更新自己。
ConcreteSubject
被觀察者物件,實現了被觀察者介面,同時有一個List集合,用以儲存註冊的觀察者,等需要通知觀察者時,遍歷該集合即可。注意,該集合的泛型引數應該是Observer,介面型別,而不應該是具體的Observer實現類,這樣做的原因是一個被觀察者可能會有多個不同實現類的觀察者(但都實現了Observer介面),如果限定了某一個具體的型別,那麼會導致以後要加入新型別的時候而不得不修改當前類,耦合度過高,這是一個非常不好的行為。
ConcreteObserver
實現了update()方法。

實現步驟

1.建立介面和抽象類

public interface Observer {    
      public String getmName();    
      void update(String weather);
}
public abstract class Subject {    
        //儲存觀察者的集合    
        public List<Observer> observers=new ArrayList<Observer>();    
        /**     
         * 新增觀察者    
         * @param
observer */
public void attach(Observer observer){ observers.add(observer); System.out.println(observer.getmName()+"訂閱天氣預報"); } /** * 移除觀察者 */ public void detach(Observer observer){ observers.remove(observer); System.out.println(observer.getmName()+"取消訂閱天氣預報"); } /** * 通知所有的觀察者改變狀態 */ public void notifyObservers(String weather){ for(Observer observer:observers){ observer.update(weather); } }}

2.實現觀察者介面

public class ObserserPeople implements Observer {    
    private String mName;    
    public ObserserPeople(String name){        
    this.mName=name;    
    }    
public void update(String weather) {        
    System.out.println(mName+"收到天氣預報訊息"+weather);    
    }    
public String getmName() {        
    return mName;   
   }}

3.繼承被觀察者抽象類

public class WeatherSubject extends Subject {    
     public void change(String weather){        
     notifyObservers(weather);   
     }}

這樣我們就寫完了,下面我們編寫一個測試類:

public class Test {    
    public static void main(String[] args) {        
    Observer observer=new ObserserPeople("校長");        
    Observer observer2=new ObserserPeople("主任");        
    Observer observer3=new ObserserPeople("老師");        
    WeatherSubject subject=new WeatherSubject();        
    subject.attach(observer);        
    subject.attach(observer2);        
    subject.attach(observer3);        
    subject.change("下個周即將下雪!!!");        
    subject.detach(observer3);        
    subject.change("下週不下雪了!");    
    }}

輸出結果如下:

校長訂閱天氣預報
主任訂閱天氣預報
老師訂閱天氣預報
校長收到天氣預報訊息下個周即將下雪!!!
主任收到天氣預報訊息下個周即將下雪!!!
老師收到天氣預報訊息下個周即將下雪!!!
老師取消訂閱天氣預報
校長收到天氣預報訊息下週不下雪了!
主任收到天氣預報訊息下週不下雪了!

通過上面例子,可以看出,當觀察者訂閱了被觀察者時,被觀察者改變立馬會通知觀察者,觀察者就會執行update()方法。當然,我在這裡沒有做實現。具體可以更具業務邏輯來進行實現。