設計模式(四)——觀察者設計模式
阿新 • • 發佈:2018-12-26
今天在做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個隨機數,每產生一個隨機數都通知所有的觀察者。
如上所述,觀察者設計模式就是這個樣子的。