观察者模式

来源:互联网 发布:软件下载模板 编辑:程序博客网 时间:2024/06/14 14:47

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有的观察者对象,让他们可以自动更新自己。

观察者模式的类图:


  • 抽象主题(Subject):主题对象可以把所有的观察者对象保存在一个容器中,并且抽象主题提供删除和注册观察者的方法。
  • 抽象观察者(Observer):是所有具体的观察者的接口,在得到抽象主题发生变化时更新自己的状态。
  • 具体主题(ConcreteSubject):在具体主题的内部状态发生变化时,给所有登记过的观察者发出通知。
  • 具体观察者(ConcreteObserver):存储于主题相符的状态,具体观察者实现抽象观察者的更新方法。
抽象主题:
public interface Subject {//注册观察者public void attach(Observer observer);//移除观察者public void remove(Observer observer);//通知所有观察者已经更新状态void notifyAllObserver();}
具体主题:
public class ConcreteSubject implements Subject {private int state;public int getState() {return state;}public void setState(int state) {this.state = state;// 主题状态改变,通知所有观察者this.notifyAllObserver();}// 使用ArrayList管理观察者private ArrayList<Observer> list = new ArrayList<Observer>();@Overridepublic void attach(Observer observer) {list.add(observer);}@Overridepublic void remove(Observer observer) {list.remove(observer);}@Overridepublic void notifyAllObserver() {// 通知所有观察者for (Observer o : list) {o.update(this);}}}
抽象观察者:
public interface Observer {// 更新状态public void update(Subject subject);}
具体观察者:
public class ConcreteObserver implements Observer {private int myState;private String myName;public ConcreteObserver(String _name) {this.myName = _name;}@Overridepublic void update(Subject subject) {// 得到状态myState = ((ConcreteSubject) subject).getState();System.out.println("观察者: " + this.myName + ":--->" + myState);}}
客户端类:
public class Client {public static void main(String[] args) {// 得到具体主题ConcreteSubject cs = new ConcreteSubject();ConcreteObserver co1 = new ConcreteObserver("观察者甲");ConcreteObserver co2 = new ConcreteObserver("观察者乙");ConcreteObserver co3 = new ConcreteObserver("观察者丙");// 注册观察者cs.attach(co1);cs.attach(co2);cs.attach(co3);System.out.println("具体主题状态改变为 3");System.out.println("******************");cs.setState(3);System.out.println("具体主题状态改变为 6");System.out.println("******************");cs.setState(6);}}
运行客户端类控制台会输出以下结果:
具体主题状态改变为 3******************观察者: 观察者甲:--->3观察者: 观察者乙:--->3观察者: 观察者丙:--->3具体主题状态改变为 6******************观察者: 观察者甲:--->6观察者: 观察者乙:--->6观察者: 观察者丙:--->6
使用观察者模式应该重点注意两个问题:
  1. 广播链的问题: 如果一个对象既是观察者也是被观察者,比如数据库中的触发器,A表插入数据后,B表会同时插入数据;B表插入数据后,C表会同时插入数据......这样数据库基本就毁掉了!建议在观察者模式中,最多出现一个对象同时作为观察者和被观察者(消息最多传递两次)。
  2. 异步处理问题:如果观察者很多,处理时间比较长,只能采用异步处理的方式,这是需要考虑线程安全以及队列的问题。

观察者模式的优缺点:
优点:
  1. 观察者模式在观察者和被观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者的聚集,每一个具体观察者都符合抽象观察者的接口。被观察者并不“认识”具体的观察者。
  2. 观察者模式支持广播通信,被观察者会向所有登记过的观察者发出通知。
缺点:
  1. 如果一个被观察者有很多直接或者间接的观察者,一一通知观察者会花费很多时间。
  2. 如果被观察者之间存在循环依赖,那么会出现循环调用,导致系统崩溃。
  3. 如果被观察者通知观察者是采用其他线程进行时,应该避免线程安全问题。
  4. 观察者虽然可以知道被观察者发生变化,但是不能知晓具体是怎么发生变化的。
1 0
原创粉丝点击