讀書筆記 僅供參考
簡述
觀察者模式,當觀察對象的狀态發生變化時,會通知給觀察者。适用于根據對象狀态進行相應處理的場景。
角色和 UML
Subject
該角色表示觀察對象,定義了注冊觀察者和删除觀察者的方法,同時聲明了擷取現在狀态的方法。
ConcreteSubject
具體的被觀察對象,自身狀态改變後,會通知已經注冊的 Observer 對象。
Observer
負責接收來自 Subject 角色的狀态變化的通知。
ConcreteObserver
具體的 Observer,當它的 update 方法被調用後,回去擷取要觀察的對象的最新狀态。
UML
例子
例程是一個自動生成數字,通知觀察者展示數字的程式。
public interface Observer {
//讓被觀察者通知觀察者狀态已經改變
void update(NumberGenerator generator);
}
// 以數字形式顯示觀察到的數值
public class DigitObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.println("DigitObserver: " + generator.getNumber());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
// 将觀察到的數值以 ***** 的方式顯示出來
public class GraphObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.println("GraphObserver: ");
int count = generator.getNumber();
for (int i = 0; i < count; i++){
System.out.print("*");
}
System.out.println();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
//作為 Subject 被觀察者
public abstract class NumberGenerator {
private List<Observer> observers = new ArrayList<>();
public void addObservers(Observer observer) {
observers.add(observer);
}
public void deleteObserver(Observer observer) {
observers.remove(observer);
}
// 向 Observer 發生通知
public void notifyObserers() {
Iterator<Observer> it = observers.iterator();
while (it.hasNext()) {
Observer o = it.next();
o.update(this);
}
}
//擷取數值
public abstract int getNumber();
//生成數值
public abstract void execute();
}
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 < 20; i++) {
number = random.nextInt(50);
notifyObserers();
}
}
}
public class Main {
public static void main(String[] args) {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
generator.addObservers(observer1);
generator.addObservers(observer2);
generator.execute();
}
}
結果
UML
要點
- 實作了可替換性,Subject 不用關注 Observer 的實作
- Observer 可能會有一定的順序要求
- 當 Observer 對 Subject 産生影響時,注意産生循環調用
- Observer 并不是主動的去觀察,而是被動的接收通知