《Head First Design Pattern》一书中对观察者模式的定义如下:
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.
观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
从根本上说,该模式必须包含两个角色:观察者和被观察对象。下面是设计模式中包含角色的UML类图(来自百度百科)。
观察者(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
被观察对象(Subject)发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者。
下面举这样一个例子:比如一个小游戏,A说出一个十进制的数,B说出其对应的二进制结果,C说出其对应的八进制结果,D说出其对应的十六进制结果。
使用观察者模式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();
}
实体被观察者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();
}
}
}
实体观察者B:游戏中的B,将A给的数字转成二进制
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));
}
}
}
实体观察者D:游戏中的D,将A给的数字转成十六进制
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));
}
}
}
观察者模式测试代码:我们开始做游戏了
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);
}
}
运行结果:
12=1100
12=0xc
-1=11111111111111111111111111111111
-1=0xffffffff
其实Java JDK本身提供了设计模式等额实现:
java.util.Observer是一个接口,观察者接口,相当于我们上面的IObserver接口。我们需要实现一个观察者的时候只需要实现这个接口就OK了。
java.util.Observable是一个类,被观察者类,我们需要实现一个被观察者的时候只需要继承这个类就OK了。
原文:http://blog.csdn.net/theonegis/article/details/44966399