Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。 《设计模式》一书对Observer是这样描述的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。别名:依赖(Dependents)、发布-订阅(Publish-Subscribe)。
原理:由四部分组成抽象目标类,具体目标类,抽象观察者类,具体观察者类
举个例子,父母做为孩子(被观察者)的监护人(观察者),孩子发生什么事一般都会通知给父母。下面的代码就模拟这一过程:
import java.util.Vector;
// 被观察者 interface Subject { public void attach(Observer observer);
public void detach(Observer observer);
void notifyObs();
public void setState(String string); }
class Children implements Subject { static private Vector<Observer> obs;// 一个存储观察者的序列 static private String state = null; static { obs = new Vector<Observer>(); }
public void attach(Observer o) { obs.addElement(o); }
public void detach(Observer o) { obs.removeElement(o); }
public void setState(String str) { state = str; }
public String getState() { return state; }
public void notifyObs() { for (Observer o : obs) { o.update(this); } } }
// 观察者 interface Observer { public void update(Children child); }
class Mother implements Observer { public void update(Children child) { if (child.getState().equals("fight")) { System.out.println("告诉Mother,他和别人打架了"); } else if (child.getState().equals("scholarship")) { System.out.println("告诉Mother,他得到了奖学金"); } } }
class Father implements Observer { public void update(Children child) { if (child.getState().equals("fight")) { System.out.println("告诉Father,他和别人打架了"); } else if (child.getState().equals("scholarship")) { System.out.println("告诉Father,他得到了奖学金"); } } }
// 测试类 public class Clients {
public static void main(String[] args) { Subject child = new Children(); Observer parent = new Father(); Observer mother = new Mother();
child.attach(parent); child.attach(mother);
child.setState("fight"); child.notifyObs(); child.setState("scholarship"); child.notifyObs(); } }
使用时机: 1. 当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象有待改变时, 应该考虑使用观察者模式; 2. 一个抽象模型有两个方面,其中一个方面依赖于另一方面, 这时用观察者模式可以将这两者封闭在独立的对象中使它们各自独立地改变和复用; 3. 观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。 JDK提供了对observer设计模式的支持: - 通过java.util.Observable类扮演Subject角色,一个类只需通过继承java.util.Observable类便可担当ConcreteSubject角色; - 通过java.util.Observer接口扮演Observer角色,一个类只需实现java.util.Observer接口便可担当ConcreteObserver角色。 - java.util.Observable的实现类通过调用setChanged()方法以及notifyObservers(Object)方法便可简单地通知Observer。 个人理解: 被观察的对象在创建后,通过add或者remove来添加或者删除观察者,被观察的对象即subject需要在自身状态发生改变的时候主动将通知发给观察者。 误解:这里所说的观察者并不能主动的去发现问题或者状态的改变,而是被动的等待通知后根据状况的改变做一些处理。