Java 设计模式系列(十五)观察者模式(Observer)

java

Java 设计模式系列目录(https://www.cnblogs.com/binarylei/p/10198698.html)

  1. Java 设计模式系列(十五)观察者模式(Observer)
  2. Java 设计模式系列(十五)Spring 中的监听器模式

观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

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

一、观察者模式的结构

  • Subject:目标对象,通常具有如下功能:

    1. 一个目标可以被多个观察者观察

    2. 目标提供对观察者注册和退订的维护

    3. 当目标的状态发生变化时,目标负责通知所有注册的、有效的观察者

  • Observer:定义观察者的接口,提供目标通知时对应的更新方法,这个更新方法进行相应的业务处理,可以在这个方法里面回调目标对象,以获取目标对象的数据。

  • ConcreteSubject:具体的目标实现对象,用来维护目标状态,当目标对象的状态发生改变时,通知所有注册有效的观察者,让观察者执行相应的处理。

  • ConcreteObserver:观察者的具体实现对象,用来接收目标的通知,并进行相应的后续处理,比如更新自身的状态以保持和目标的相应状态一致。

一个目标可以有任意多个观察者对象,一旦目标的状态发生了改变,所有注册的观察者都会得到通知,然后各个观察者会对通知作出相应的响应,执行相应的业务功能处理,并使自己的状态和目标对象的状态保持一致。

源代码

(1) Subject

/**

* 目标对象,它知道观察它的观察者,并提供注册和删除观察者的接口

*/

public class Subject {

/** 用来保存注册的观察者对象 */

private List<Observer> observers = new ArrayList<Observer>();

/** 注册观察者对象 */

public void attach(Observer observer) {

observers.add(observer);

}

/** 删除观察者对象 */

public void detach(Observer observer) {

observers.remove(observer);

}

/** 通知所有注册的观察者对象 */

protected void notifyObservers() {

for(Observer observer : observers){

observer.update(this);

}

}

}

(2) ConcreteSubject

/**

* 具体的目标对象,负责把有关状态存入到相应的观察者对象,

* 并在自己状态发生改变时,通知各个观察者

*/

public class ConcreteSubject extends Subject {

/** 示意,目标对象的状态 */

private String subjectState;

public String getSubjectState() {

return subjectState;

}

public void setSubjectState(String subjectState) {

this.subjectState = subjectState;

//状态发生了改变,通知各个观察者

this.notifyObservers();

}

}

(3) Observer

/**

* 观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象

*/

public interface Observer {

/** 通知观察者 */

public void update(Subject subject);

}

(4) ConcreteObserver

/**

* 具体观察者对象,实现更新的方法,使自身的状态和目标的状态保持一致

*/

public class ConcreteObserver implements Observer {

/** 示意,观者者的状态 */

private String observerState;

public void update(Subject subject) {

// 具体的更新实现

//这里可能需要更新观察者的状态,使其与目标的状态保持一致

observerState = ((ConcreteSubject)subject).getSubjectState();

}

}

二、Java 提供的观察者模式

2.1 Java 中的观察者模式

其中 Observer 和 Observable 是 java.util 下的包。

(1) ConcreteSubject

public class ConcreteSubject extends Observable {

/** 示意,目标对象的状态 */

private String subjectState;

public String getSubjectState() {

return subjectState;

}

public void setSubjectState(String subjectState) {

this.subjectState = subjectState;

// 状态发生了改变,通知各个观察者

this.setChanged();

this.notifyObservers(subjectState);

}

}

(2) ConcreteObserver

public class ConcreteObserver implements Observer {

/** 示意,观者者的状态 */

private String observerState;

@Override

public void update(Observable o, Object obj) {

//这是采用推的方式

System.out.println("目标推过来的内容是:" + obj);

//这是获取拉的数据

System.out.println("主动到目标对象去拉的内容是:" + ((ConcreteSubject)o).getSubjectState());

}

}

2.2 Java 中的监听者模式

在 java.util 中有两个与事件监有关的类

  • EventObject 事件源,对事件源进行了简单的封装

  • EventListener 事件监听者,标记接口

三、总结

(1) 推模型和拉模型

在观察者模式中,又分为推模型和拉模型两种方式。

  • 推模型:主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。

  • 拉模型:主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种模型的实现中,会把主题对象自身通过 update() 方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。


每天用心记录一点点。内容也许不重要,但习惯很重要!

以上是 Java 设计模式系列(十五)观察者模式(Observer) 的全部内容, 来源链接: utcz.com/z/392668.html

回到顶部