观察者模式的宗旨:在多个对象之间定义一个一对多的关系,当一个对象状态改变的时候,其他所有的依赖于这个对象的对象能够得到通知,并自动更新。
观察者模式在Swing中得到了广泛应用。当客户单击按钮时,程序中许多对象都会对此做出反应。在Swing中,关注Swing组件变化的类被称为“监听器”,这就是观察者模式的应用。
为了支持观察者模式,Java类库中的java.util包中提供了Observable类和Observer接口。
我们现在举一个例子来说明观察者模式。
在网上商店的应用中,如果我们希望产品的名称被更改了后,系统会自动在控制台打印新名称,则就可以使用观察者模式。此时,产品类Product就需要继承Observable类,产品观察者类NameObserver则需要实现Observer接口。
先看类图:
代码实现:
1. Product.java
import java.util.Observable; public class Product extends Observable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; setChanged(); notifyObservers(name); } } |
注意:在setName()方法中,调用了Observalbe类的setChanged()和notifyObservers()方法。
setChanged()方法将触发Observable代码将这次改变广播出去;而notifyObservers()方法调用所有注册的观察者对象的update()方法。(有点啰嗦)
Product类不需要维护所有监视它的对象的引用,这些监视的对象将在实际的代码中TestObserver.java被注册。
2. NameObserver.java
import java.util.Observable; import java.util.Observer; public class NameObserver implements Observer { public void update(Observable o, Object arg) { String name = (String)arg; System.out.println("Set Name: " + name); } } |
该类实现了Observer接口,当Product对象的setName()方法被调用后,该类的update方法会自动被调用,并在控制台输入新的产品名称。
3. TestObserver.java
public class TestObserver { public static void main(String[] args) { NameObserver nameObserver = new NameObserver(); Product product = new Product(); product.addObserver(nameObserver); product.setName("Cat1"); } } |
该类是一个测试程序,实例化NameObserver和Product,并将NameObserver的实例注册给Product实例(通过调用Product.addObserver来注册),用以实现监听。当程序给Product的setName()方法被调用后,NameObserver实例的update()方法马上就会得到通知并输出新的产品名称。