技术共享

设计模式-观察者模式

2024-07-08

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

一、观察者模式的核心思想

观察者(Observer)模式又名发布一订阅(Publish/Subscribe)模式。GOF 给观察者模式如下定义:定义对象间的一种一对多的依赖关系,让多个观察者对象同时关注同一个对象,当该对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
如下图所示,观察者模式中包含5类对象。
在这里插入图片描述

  • 目标接口 Subject:目标接口定义了增加观察者 attach()、删除观察者 detach()和通知观察者notifyObservers()3个接口,并定义自身的操作函数operation()。
  • 抽象目标类 AbstractSubject:该类定义了观察者的集合对象 vect,用来存储被添加的观察者对象列表;并实现增加观察者 attach()、删除观察者 detach()和通知观察者 notifyObservers()3个函数来更新该列表,以及通知所有的观察者对象更新自己。
  • 具体目标类MySubiect:继承自抽象目标类 AbstractSubiect,并编写具体的操作函数实现operation(),在该函数中可以调用 notifyObservers()来通知所有的观察者更新自己。
  • 观察者接口Observer:为那些在目标类发生改变时需要获得通知的对象定义一个统一的接口 update(),当调用 notifyObservers()时将会调用 update()函数来更新自己。
  • 具体观察者:可以定义多个观察者对象,如 Observer1、Observer2,用来编写统一的更新函数。客户端 Test 则可以通过为Subject类添加观察者 Observer 来实现监控。

下面来看具体的实现。

(1) 观察者接口 Observer.java定义了一个统一的更新接口update()。其源代码如下程序所示。

package behavior.observer;


/**
* @author Minggg
* 观察者接口
*/
public interface Observer {

	public void update();
}

(2) 观察者实现类 Observer1.java 是一个观察者的具体实现,其更新函数用来往控制台输出一个字符串。其源代码如下程序所示。

package behavior.observer;


/**
* @author Minggg
* 具体观察者
*/
public class Observer1 implements Observer {

	public void update(){ 
		System.out.println("观察者1得到通知!");
	}
}

(3) 观察者实现类 Observer2.java是另一个观察者的具体实现,其更新函数用来往控制台输出个字符串。其源代码如下程序所示。

package behavior.observer;


/**
* @author Minggg
* 具体观察者
*/
public class Observer2 implements Observer {

	public void update(){ 
		System.out.println("观察者2得到通知!");
	}
}

(4) 被观察者接口Subject.java中定义了3个操作观察者的接口函数,并定义了一个具体的操作函数接口,表示自身的功能。其源代码如下程序所示。

package behavior.observer;


/**
* @author Minggg
* 被观察者接口
*/
public interface Subject {

	// 增加观察者
	public void attach(Observer observer);
	// 删除观察者
	public void detach(Observer observer);
	// 通知所有观察者
	public void notifyObservers();
	// 自身的操作接口
	public void operation();
}

(5) 被观察者抽象类 AbstractSubject.java中提供了一个 Vector列表 vect,用来保存所有的观察者对象,并编写实现函数来操作该列表对象。其源代码如下程序所示。

package behavior.observer;

import java.util.Enumeration;
import java.util.Vector;


/**
* @author Minggg
* 被观察者抽象类
*/
public abstract class AbstractSubject implements Subject {

	private Vector