《Head First Design Pattern》1書(shū)中對(duì)視察者模式的定義以下:
The Observer Pattern defines a one-to-many dependency objects so that when one object changes state, all of its dependents are notified and updated automatically.
視察者設(shè)計(jì)模式定義了對(duì)象間的1種1對(duì)多的依賴關(guān)系,以便1個(gè)對(duì)象的狀態(tài)產(chǎn)生變化時(shí),所有依賴于它的對(duì)象都得到通知并自動(dòng)刷新。
從根本上說(shuō),該模式必須包括兩個(gè)角色:視察者和被視察對(duì)象。下面是設(shè)計(jì)模式中包括角色的UML類圖(來(lái)自百度百科)。
視察者(Observer)將自己注冊(cè)到被視察對(duì)象(Subject)中,被視察對(duì)象將視察者寄存在1個(gè)容器(Container)里。
被視察對(duì)象(Subject)產(chǎn)生了某種變化,從容器中得到所有注冊(cè)過(guò)的視察者,將變化通知視察者。
下面舉這樣1個(gè)例子:比如1個(gè)小游戲,A說(shuō)出1個(gè)10進(jìn)制的數(shù),B說(shuō)出其對(duì)應(yīng)的2進(jìn)制結(jié)果,C說(shuō)出其對(duì)應(yīng)的8進(jìn)制結(jié)果,D說(shuō)出其對(duì)應(yīng)的106進(jìn)制結(jié)果。
使用視察者模式A可以作為被視察者(Subject),B、C、D可以作為視察者(Observer)。
下面是Java代碼示例:
視察者接口:
public interface IObserver {
public void update();
}
被視察者接口:
public interface ISubject {
public void addObserver(IObserver o);
public void deleteObserver(IObserver o);
public void notifyObservers();
}
實(shí)體被視察者A:就是游戲中的A
public class Number implements ISubject {
private List<IObserver> observers;
private int number;
public Number() {
observers = new ArrayList<IObserver>();
}
public void setNumber(int number) {
this.number = number;
notifyObservers();
}
public int getNumber() {
return number;
}
@Override
public void addObserver(IObserver o) {
observers.add(o);
}
@Override
public void deleteObserver(IObserver o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (IObserver observer : observers) {
observer.update();
}
}
}
實(shí)體視察者B:游戲中的B,將A給的數(shù)字轉(zhuǎn)成2進(jìn)制
public class BinTranslator implements IObserver {
private ISubject subject;
public BinTranslator(Number number) {
subject = number;
subject.addObserver(this);
}
@Override
public void update() {
if (subject instanceof Number) {
Number number = (Number) subject;
int inum = number.getNumber();
System.out.println(inum + "=" + Integer.toBinaryString(inum));
}
}
}
實(shí)體視察者D:游戲中的D,將A給的數(shù)字轉(zhuǎn)成106進(jìn)制
public class HexTranslator implements IObserver {
private ISubject subject;
public HexTranslator(Number number) {
subject = number;
subject.addObserver(this);
}
@Override
public void update() {
if (subject instanceof Number) {
Number number = (Number) subject;
int inum = number.getNumber();
System.out.println(inum + "=0x" + Integer.toHexString(inum));
}
}
}
視察者模式測(cè)試代碼:我們開(kāi)始做游戲了
public class ObserverPattern {
@SuppressWarnings("unused")
public static void main(String[] args) {
Number number = new Number();
IObserver bin = new BinTranslator(number);
IObserver hex = new HexTranslator(number);
number.setNumber(12);
number.setNumber(-1);
}
}
運(yùn)行結(jié)果:
12=1100
12=0xc
⑴=11111111111111111111111111111111
⑴=0xffffffff
其實(shí)Java JDK本身提供了設(shè)計(jì)模式等額實(shí)現(xiàn):
java.util.Observer是1個(gè)接口,視察者接口,相當(dāng)于我們上面的IObserver接口。我們需要實(shí)現(xiàn)1個(gè)視察者的時(shí)候只需要實(shí)現(xiàn)這個(gè)接口就OK了。
java.util.Observable是1個(gè)類,被視察者類,我們需要實(shí)現(xiàn)1個(gè)被視察者的時(shí)候只需要繼承這個(gè)類就OK了。