Java设计模式——观察者模式

本文详细解析了观察者模式的定义、设计原则、关键要点,并通过Java JDK内置的Observable类和Observer接口具体展示了如何在实际项目中应用观察者模式,包括如何在Swing GUI框架中高效地传递消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

观察者模式

观察者模式——定义了对象之间一对多的依赖关系,这样一来,当一个对象改变状态时,所有的依赖者都会收到通知并更新。

设计原则

针对接口编程,不针对实现编程

主题与观察者都是用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者

多用组合,少用继承

观察者模式利用“组合”将许多观察者组合进主题之中,对象之间的这种关系不是通过继承产生的,而是在运行时用组合的方式产生的

要点
  • 使用此模式时,可以从被观察者处推(push)或拉(pull)数据
    若使用拉(pull)的方式,如果主题决定扩展功能,新增更多的状态,就不必更改对每位观察者的调用,只需要改变自己来允许更多的getter()方法取得新增的状态

更多关于利用推或拉传递消息的比较

  • Swing大量使用观察者模式,许多GUI框架也是如此

java内置的观察者模式

以下内容转载自

java jdk中定义了:Observable对象(被观察者)和Observer接口(观察者).

它们的关系可总结如下:

  • Observable和Observer是一对多的关系,也就是说一旦Observable状态变化,它就要负责 通知所有和它有关系的Observer,然后做相应的改变
  • Observable不会主动去通知各个具体的Observer其状态发生了变化,而是提供一个注册 接口供Observer使用,任何一个Observer如果想要被通知,则可以使用这个接口 来注册
  • 在Observable中有一个集合和一个状态控制开关,所有注册了通知的Observer会被保 存在这个集合中.这个控制开关就是用来控制Observable是否发生了变化,一旦发生了变 化,就通知所有的Observer更新状态

我们先看一下jdk是如何实现的。被观察者的**抽象类**java.util.Observable
/怎么没有抽象函数呢??/

package java.util;

public class Observable {
  private boolean changed = false;
  private Vector obs;

  /**
   * 创建被观察者时就创建一个它持有的观察者列表,注意,这个列表是需要同步的。
   */
  public Observable() {
    obs = new Vector();
  }

  /**
   * 添加观察者到观察者列表中去
   */
  public synchronized void addObserver(Observer o) {

    if (o == null)
      throw new NullPointerException();
    if (!obs.contains(o)) {
      obs.addElement(o);
    }
  }

  /**
   * 删除一个观察者
   */ 
  public synchronized void deleteObserver(Observer o) {
    obs.removeElement(o);
  }

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

  /**
   * 通知操作,即被观察者发生变化,通知对应的观察者进行事先设定的操作,这个方法接受一个参数,这个参数一直传到观察者里,以供观察者使用
   */ 
  public void notifyObservers(Object arg) {
    Object[] arrLocal;
    synchronized (this) {
      if (!changed)
        return;
      arrLocal = obs.toArray();
      clearChanged();
    }
    for (int i = arrLocal.length-1; i>=0; i--)
      ((Observer)arrLocal[i]).update(this, arg);
  }

  public synchronized void deleteObservers() {
    obs.removeAllElements();
  }

  protected synchronized void setChanged() {
    changed = true;
  }

  protected synchronized void clearChanged() {
    changed = false;
  }


  public synchronized boolean hasChanged() {
     return changed;
  }

  public synchronized int countObservers() {
    return obs.size();
  }
}

当我们自己的被观察者继承这个Observable类是,我们就自动的获取到被观察者的一切条 件了。很方便是不是,这也是为什么sun要把Observable放到java.util包中的原因,就是 为了方便开发者。

下面我们再看一下观察者的 接口 java.util.Observer

package java.util;

public interface Observer {
  void update(Observable o, Object arg);
}

接口中就只有一个方法,update,方法中有两个参数,Observable和一个object,第一个 参数就是被观察的对象,而第二个参数就得看业务需求了,需要什么就传进去什么。我们 自己的观察者类必须实现这个方法,这样在被观察者调用notifyObservers操作时被观察者 所持有的所有观察者都会执行update操作了,见下图:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值