1. 程式人生 > >設計模式(四)——觀察者設計模式

設計模式(四)——觀察者設計模式

今天在做Oozie的專案的時候,想要對後臺的作業任務進行實時監控,想了好久都沒有辦法,因為沒有原始碼,只有介面,所以最終沒有搞成,用了自我感覺比較噁心的定時請求的方法....額,說了這麼多好像和主題沒什麼關係,那好吧,進入正題。我們很多時候都希望有一個類或者什麼可以發現某個狀態的變化,一旦狀態發生變化,我們就可以得到通知,就像是有一個觀察者一直在看著這個狀態,一旦變化,他就告訴所有需要知道該變化的人。這就是——觀察者設計模式

好了,廢話不多說,上類圖(其實自己也發現,有了類圖,理解問題就變得簡單和直觀很多了)。

這個類圖,看了以後,其實還有很多細節,用語言來描述的話,其實關鍵點就在於:當產生數字的時候,給所有的觀察者通知,這個通知的完成,是因為觀察者都有一個產生數字的抽象類的引用。下面我們來看看程式碼的實現吧。

產生數字的抽象類:

package com.xdccl.zwj.ObserverDesignPattern;

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

public abstract class NumberGenerator {
	private List<Observer> observers = new ArrayList<Observer>() ;
	//新增觀察者
	public void addObserver(Observer observer){
		observers.add(observer) ;
	}
	//刪除觀察者
	public void delObserver(Observer observer){
		observers.remove(observer);
	}
	//通知觀察者
	public void notifyObserver(){
		Iterator<Observer> iterator = observers.iterator() ;
		while(iterator.hasNext()){
			Observer o = iterator.next() ;
			o.update(this) ;
		}
	}
	public abstract int getNum() ;
	public abstract void generate() ;
}
繼承上面抽象類的隨機產生隨機數字的類:
package com.xdccl.zwj.ObserverDesignPattern;

import java.util.Random;

public class RandomNumberGenerator extends NumberGenerator {
	private Random random = new Random();//隨機數  
    private int number;   //數字  
	@Override
	public int getNum() {
		return number;
	}

	@Override
	public void generate() {
	 for(int i=0 ; i < 5; i++) {  
            number = random.nextInt(10);//產生10以內的隨機數  
            notifyObserver();  //如果有新產生的數字,就發出通知給所有註冊過的觀察者  
        }
	}

}
觀察者介面:
package com.xdccl.zwj.ObserverDesignPattern;

public interface Observer {
	public abstract void update(NumberGenerator generator) ;
}
數字觀察者:
package com.xdccl.zwj.ObserverDesignPattern;

public class NumberObserver implements Observer {

	@Override
	public void update(NumberGenerator generator) {
		System.out.println("NumberObserver:"+ generator.getNum());  
        try {  
            Thread.sleep(1000 * 3); //為了能清楚的看到輸出,休眠3秒鐘。  
       }catch(InterruptedException e) {  
             e.printStackTrace();  
        }  
	}

}
客戶端:
package com.xdccl.zwj.ObserverDesignPattern;

public class Client {
	public static void main(String args[]){
		//例項化數字產生物件  
        NumberGenerator generator = new RandomNumberGenerator();  
        //例項化觀察者  
        Observer observer = new NumberObserver();  

        //註冊觀察者  
        generator.addObserver(observer);  
          
        generator.generate(); //產生數字
	}
}
如果發現下列結果,應該就沒有問題:

NumberObserver:3
NumberObserver:9
NumberObserver:1
NumberObserver:1
NumberObserver:1

這裡產生五次是因為,我設定的是產生5個隨機數,每產生一個隨機數都通知所有的觀察者。

如上所述,觀察者設計模式就是這個樣子的。