前言
Observer本來的意思是“觀察者”,但是實際上Observer角色並非主動的去觀察,而是被動的接收來自觀察物件角色的通知,因此,Observer也被成為Publish-Subscribe(釋出-訂閱)模式。它定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件。這個主題物件在狀態上發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己。對於觀察者模式應用的也很多,例如大家最熟悉的MVC框架就是觀察者模式的典型應用,訊息推送,事件監聽等都是觀察者模式的最好詮釋。
在圖解設計模式中是通過一個觀察者觀察一個會生成數值的物件,並將生成的數值通過不同的觀察者顯示出來。照例通過如下UML類圖簡單熟知下流程。
觀察者Observer
Observer角色負責接收來自觀察者物件角色的狀態變化的通知,它表示“觀察者”,具體的觀察者會實現該介面,用於生成數字的觀察物件角色類NumberGenerator類會呼叫update方法並且將生成的數字變化的通知傳送給Observer。
public interface Observer {
public abstract void update(NumberGenerator generator);
}複製程式碼
觀察物件NumberGenerator
該類是用於生成數值的抽象類,提供了獲取數值和生成數值的抽象方法,需要子類去實現。並且提供了一個存放觀察數值變化的觀察者物件的List。方法addObserver(Observer observer)和deleteObserver(Observer observer)用註冊觀察者和刪除觀察者,重要的一步就是當有資料變化時呼叫notifyObservers方法通知所有觀察者。
public abstract class NumberGenerator {
private ArrayList observers=new ArrayList();
public void addObserver(Observer observer){
observers.add(observer);
}
public void deleteObserver(Observer observer){
observers.remove(observer);
}
public void notifyObservers(){
Iterator iterator=observers.iterator();
while (iterator.hasNext()){
Observer observer= (Observer) iterator.next();
observer.update(this);
}
}
public abstract int getNumber();
public abstract void execute();
}複製程式碼
具體的觀察物件RandomNumberGenerator
對於該具體觀察者物件,它主要是用來生成隨機數,並通過notifiObservers方法把每一次生成的結果通知給所有已註冊的觀察者
public class RandomNumberGenerator extends NumberGenerator {
private Random random = new Random();
private int number;
@Override
public int getNumber() {
return number;
}
@Override
public void execute() {
for (int i = 0; i < 5; i++){
number=random.nextInt(30);
notifyObservers();
}
}
}複製程式碼
具體觀察者
具體觀察者實現了觀察者Observer介面,當update方法被呼叫時會去獲取要觀察的物件的最新資料,在此寫了兩個具體的觀察者。
public class DigitObserver implements Observer{
@Override
public void update(NumberGenerator generator) {
System.out.println("DigitObserver:"+generator.getNumber());
}
}
public class GraphObserver implements Observer{
@Override
public void update(NumberGenerator generator) {
System.out.println("GraphObserver:"+generator.getNumber());
}
}複製程式碼
測試類
public class Main {
public static void main(String[] args) {
NumberGenerator generator=new RandomNumberGenerator();
Observer observer1=new DigitObserver();
Observer observer2=new GraphObserver();
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();
}
}複製程式碼
輸出資訊:
DigitObserver:2
GraphObserver:2
DigitObserver:19
GraphObserver:19
DigitObserver:26
GraphObserver:26
DigitObserver:10
GraphObserver:10
DigitObserver:14
GraphObserver:14複製程式碼
通過上面測試程式碼,你應該發現對於觀察者物件可以有多個觀察者對其作出響應,如某些訂閱專欄,它可以被很多人訂閱,當專欄有內容更新時,它會給每一個人傳送推送,我們在訂閱專欄後,並不需要我們一直去等待它的內容更新,而不能去做自己的事情。
好了,今天的觀察者模式到此結束。有問題歡迎留言指出,Have a wonderful day .
如需文章中所寫程式碼,請移步GitHub檢視