企业项目管理、ORK、研发管理与敏捷开发工具平台

网站首页 > 精选文章 正文

Java设计模式-观察者模式(设计模式中的观察者模式)

wudianyun 2025-01-31 15:40:09 精选文章 35 ℃

观察者模式定义:观察者模式(Observer),又叫发布-订阅模式(Publish/Subscribe),是一种 行为型模式。它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

观察者模式角色构成:

1、抽象主题(Subject):也称为被观察者或发布者,它维护了一个观察者列表,并提供方法 用于注册、注销和通知观察者。

2、具体主题(Concrete Subject):也叫具体目标类被观察者,当具体主题的内部状态发生 改变时,通知所有注册过的观察者对象。

3、抽象观察者(Observer):也称为订阅者或监听器,它定义了一个接口或抽象类,包含了 观察者所需实现的方法,通常是更新方法,在主题状态改变时被调用。

4、具体观察者(Concrete Observer):实现观察者接口或抽象类的具体类,它负责接收主题 的通知并执行相应的操作。

观察者模式主要适用场景举例:

  • 事件驱动系统:如 GUI 框架中的按钮点击事件、消息通知系统等。
  • 实时数据更新系统:例如股市行情、气象监控等。
  • 模型 - 视图 - 控制器(MVC)模式:视图(observer)监听模型(subject)的变化。
  • 发布 - 订阅模式:例如博客平台的订阅功能,用户订阅了博客文章的更新,当有新文章时自动推送通知。

观察者模式的主要优点:

  • 松耦合:主题和观察者之间没有直接的依赖关系,主题只知道如何通知观察者,而不需要关心观察者的具体实现,这样可以降低代码的耦合性,增强系统的灵活性1。
  • 可扩展性:可以在运行时动态地添加新的观察者,且无需修改现有的代码。
  • 多对一通知:一个主题可以通知多个观察者,适用于广播式通信。

观察者模式Java样例

1、抽象主题(Subject)

import java.util.ArrayList;
import java.util.List;

// 主题接口,定义了注册、注销和通知观察者的方法
public interface Subject {
    void registerObserver(Observer observer);
    void unregisterObserver(Observer observer);
    void notifyObservers(String message);
}

2. 抽象观察者(Observer)

// 观察者接口,定义了接收通知的更新方法
public interface Observer {
    void update(String message);
}

3. 具体主题(ConcreteSubject)

import java.util.ArrayList;
import java.util.List;

// 具体主题类,实现了Subject接口
public class School implements Subject {
    // 存储观察者的列表
    private List observers = new ArrayList<>();
    // 学校发布的通知消息
    private String notice;

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void unregisterObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(String message) {
        this.notice = message;
        for (Observer observer : observers) {
            observer.update(notice);
        }
    }
}

4. 具体观察者(ConcreteObserver)

// 学生类,实现了Observer接口
public class Student implements Observer {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " 收到学校通知:" + message);
    }
}

5. 测试类

public class Main {
    public static void main(String[] args) {
        // 创建学校对象
        School school = new School();

        // 创建学生对象
        Student student1 = new Student("张三");
        Student student2 = new Student("李四");
        Student student3 = new Student("王五");

        // 学生注册到学校,即观察者注册到主题
        school.registerObserver(student1);
        school.registerObserver(student2);
        school.registerObserver(student3);

        // 学校发布通知
        school.notifyObservers("明天上午八点举行全校大会");
    }
}

6. 输出

张三收到学校通知:明天上午八点举行全校大会
李四收到学校通知:明天上午八点举行全校大会
王五收到学校通知:明天上午八点举行全校大会

Tags:

最近发表
标签列表