Java設計模式之從[星際爭霸的兵種升級]分析觀察者(Observer)模式
阿新 • • 發佈:2018-12-26
觀察者模式定義物件的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都會得到通知並被自動更新。
一個簡單的例子是,在星際爭霸的蟲族中有一個初級單位叫做跳狗(Zergling),玩家可以在研究中心為它升級“腎上腺素”,升級之後,跳狗的攻擊速度會翻倍。在這個模型中,我們可以看出,所有的跳狗都依賴於研究中心,當研究中心研究出腎上腺素後,通知每一個跳狗單位,它們被迫進行自我更新——升級速度加倍。在觀察者模型中,我們稱研究中心為目標(Subject),而跳狗為觀察者(Observer)。觀察者觀察目標的變化,如果目標發生了變化,那麼觀察者自身也會跟著變化。
以下是Java程式碼:
import java.util.ArrayList; abstract class Subject{ ArrayList<Observer> observers = new ArrayList<Observer>(); public void attach(Observer observer){ if (!observers.contains(observer)) observers.add(observer); } public void detach(Observer observer){ if (observers.contains(observer)) observers.remove(observer); } protected void notifyObservers(){ for (Observer o : observers){ o.update(this); } } } abstract class Observer{ Subject subject; public Observer(Subject subject){ this.subject = subject; subject.attach(this); } abstract void update(Subject subject); } class AdrenalUpgrade extends Subject{ public void upgrade(){ notifyObservers(); } } class Zergling extends Observer { public Zergling(Subject subject) { super(subject); } public void update(Subject subject) { if (subject == this.subject){ System.out.println("Zergling的腎上腺素被刺激,攻擊速度翻倍!"); } } } public class ObserverExample { public static void main(String[] args) { AdrenalUpgrade adrenalUpgrade = new AdrenalUpgrade(); Zergling z1 = new Zergling(adrenalUpgrade); Zergling z2 = new Zergling(adrenalUpgrade); Zergling z3 = new Zergling(adrenalUpgrade); Zergling z4 = new Zergling(adrenalUpgrade); Zergling z5 = new Zergling(adrenalUpgrade); Zergling z6 = new Zergling(adrenalUpgrade); Zergling z7 = new Zergling(adrenalUpgrade); adrenalUpgrade.upgrade(); } }
Subject的是目標的基類,它可以attach或detach一個Observer。Subject含有一個List用於記錄自己被哪些Observer依賴,當自身的狀態改變時,會依次呼叫每一個Observer的update()方法。例如在main方法中,我們分別建立了z1、z2……z7共7個Zergling單位,它們都attach到了AdrenalUpgrade上,當AdrenalUpgrade呼叫了upgrade()時,會給每一個Zergling發出通知,因此程式的執行結果為:
Zergling的腎上腺素被刺激,攻擊速度翻倍!
Zergling的腎上腺素被刺激,攻擊速度翻倍!
Zergling的腎上腺素被刺激,攻擊速度翻倍!
Zergling的腎上腺素被刺激,攻擊速度翻倍!
Zergling的腎上腺素被刺激,攻擊速度翻倍!
Zergling的腎上腺素被刺激,攻擊速度翻倍!
Zergling的腎上腺素被刺激,攻擊速度翻倍!
以上就是觀察者模式的一個例子。有興趣的同學可以看一看MVC(C#)結構,它可能是觀察者模式中最有名的結構之一了。