设计模式 | 观察者模式

OO原则

  • 封装变化
  • 多用组合,少用继承
  • 针对接口编程,不针对实现编程
  • 为对象之间的松耦合设计努力

观察者模式

  • 对象之间定义一对多的依赖,当一个subject对象改变状态时,依赖它的对象会收到通知,并自动更新
  • 应用:JavaBeans / RMI / GUI
  • 实现:java.util.Observable的问题在于 subject不是接口,而是抽象类
  • 细节:push/pull两种方式,push更友好;多个观察者不应该依赖特定的通知次序
  • JDK自带的观察者observable并不灵活,可以自己实现

自己实现最简单的观察者

public interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}

public interface Observer {
    void update(float temp, float humidity, float pressure);
}

public class SubjectIml implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public SubjectIml() {
        observers = new ArrayList<Observer>();
    }

    public void registerObserver(Observer o) {
        observers.add(o);
    }

    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if (i >= 0) {
            observers.remove(o);
        }
    }

    public void notifyObservers() {
        for (Observer o : observers) {
            o.update(temperature, humidity, pressure);
        }
    }

    public void measurementsChanged() {
        notifyObservers();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}

缺点:

  • 每次变更,直接push给观察者,没有在合适的时候推送
  • 缺少pull的方式
  • 可能有线程安全问题

JDK自带的观察者

  • notifyObservers方法:根据changed决定是否通知

    public void notifyObservers(Object arg) {
    /*
    * a temporary array buffer, used as a snapshot of the state of
    * current Observers.
    */
    Object[] arrLocal;

      synchronized (this) {
          /* We don't want the Observer doing callbacks into
           * arbitrary code while holding its own Monitor.
           * The code where we extract each Observable from
           * the Vector and store the state of the Observer
           * needs synchronization, but notifying observers
           * does not (should not).  The worst result of any
           * potential race-condition here is that:
           * 1) a newly-added Observer will miss a
           *   notification in progress
           * 2) a recently unregistered Observer will be
           *   wrongly notified when it doesn't care
           */
          if (!changed)
              return;
          arrLocal = obs.toArray();
          clearChanged();
      }
    
      for (int i = arrLocal.length-1; i>=0; i--)
          ((Observer)arrLocal[i]).update(this, arg);
    

    }

  • pull 方式:null代表没有更新,观察者需要调用主题对象的get()方法

    public void notifyObservers() {
    notifyObservers(null);
    }

  • 缺点:不是接口,是一个class

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值