1. 程式人生 > >手寫一個觀察者模式(JAVA Demo)

手寫一個觀察者模式(JAVA Demo)

首先理解一下觀察者模式的定義:

      定義物件間一種一對多的依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新。

直譯:

      建立一個一(Subject)對多(Observer)的關係,能夠使得當"一"變化的時候,依賴這個"一"的多也能夠同步改變。

觀察者模式所涉及的角色有:

  • 抽象主題(Subject)角色:即被觀察者(Observable)的角色,主題的抽象類,抽象主題角色把所有觀察者物件的引用儲存在一個集合裡,每個主題都可以有任意數量的觀察者,抽象主題提供一個介面可以增加和刪除觀察者物件

  • 具體主題(ConcreteSubject)角色:即具體被觀察者(ConcreteObservable),此角色將有關狀態存入具體觀察者物件,在具體主題的內部狀態發生改變時,給所有註冊過的觀察者發出通知。

  • 抽象觀察者(Observer)角色:此角色是觀察者的介面類,它定義了一個更新介面,在得到主題的通知時更新自己。

  • 具體觀察者(ConcreteObserver)角色:該主題實現抽象觀察者角色所定義的更新介面,以便在主題的狀態發生變化時更新自身的狀態。

以上就是觀察者模式的基本內容,現在要開始寫一個觀察者模式的程式碼前,請先檢查下我們的“武器”:

    在JAVA語言的API中,提供了一個Observable抽象類以及一個Observer介面,構成JAVA語言對觀察者模式的支援。

  1. Observable抽象類   抽象主題角色,具體主題類必須繼承該抽象類,同時抽象主題提供一個介面
    可以增加和刪除觀察者物件以及一個訊息通知方法。
  2. Observer介面類,抽象觀察者角色,具體觀察者必須實現該介面,同時它定義了一個更新介面,具體觀察者必須實現該更新方法。

觀察者模式需要用到的Java類

  1 java.util.Observable

    -able一般可能...的單詞字尾,Observable就是可以被觀察的,程式中的被觀察者類,需要繼承這個類。

  2 java.util.Observer

    這個是觀察者,是介面。程式中的觀察者類,需要實現這個介面中的update()方法。

下面開始講解觀察者模式的JAVA Demo:

(1)觀察者物件User  一個介面類,必須實現update方法(獲取更新訊息)

/**
 * 微信使用者是具體觀察物件
 * @author xiazheng
 *
 */
package com.Observer;

import java.util.Observable;
import java.util.Observer;

public class User implements Observer{
	private String name;
	public User(String name){
		this.name = name;
	}

	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		 System.out.println("微信使用者:"+name+",您的微信公眾號更新這些內容:"+arg);
	}
	

}

(2)被觀察者物件OfficialAccount ,需要重寫一個訊息通知方法(publishnewInfo)

/*
 * OfficialAccount是具體被觀察的物件:
 *     當它更新時,所有監聽該物件的觀察者(微信使用者)都會接收到通知
 * */
package com.Observer;

import java.util.Observable;

public class OfficialAccount extends Observable{

    /**
     * 
     * @param info  要給觀察者的資訊
     */
    public void publishNewInfo(String info){

        //標識這個Observable物件已經改變了,更具體來將就是把Observable中屬性changed置為true.
        setChanged();
        //在通知所有觀察者之前,需要判斷Observable中屬性changed是否為true,如若不為則不會發出通知。
        //具體可以看原始碼,蠻好理解的。
        notifyObservers(info);
    }
	

}

(3)測試主類

package com.Observer;

public class Test {

	public static void main(String[] args) {

        //被觀察的角色
        OfficialAccount officialAccount = new OfficialAccount();

        //觀察者
        User userBob = new User("WeChat User-Bob");
        User userTom = new User("WeChat User-Tom");
        User userMe = new User("WeChat User-Me");

        //將觀察者註冊到可觀察物件的觀察者列表中
        officialAccount.addObserver(userBob);
        officialAccount.addObserver(userTom);
        officialAccount.addObserver(userMe);

        //釋出訊息
        officialAccount.publishNewInfo("...新內容...");
        officialAccount.deleteObserver(userMe);
        System.out.println("##########################################");
        officialAccount.publishNewInfo("...新內容123...");

    }

}

測試結果:

       新增三個監聽者,三個監聽者都可以收到訊息,刪除掉一個監聽者,只有剩下兩個監聽者可以收到訊息。

      User是具體的觀察者,他們訂閱了OfficialAccount這個具體的可觀察物件,當OfficialAccount有更新時,會遍歷所有觀察者。然後給這些觀察者釋出一個更新訊息,之後User中的update方法會呼叫,這樣就達到了一對多的通知功能。