观察者模式定义对象的一种一对多的依赖关系。当一个对象的状态发生改变时。全部依赖于它的对象都会得到通知并被自己主动更新。
一个简单的样例是。在星际争霸的虫族中有一个0基础单位叫做跳狗(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#)结构。它可能是观察者模式中最有名的结构之中的一个了。