前言
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 .