Java 设计模式(行为型)-观察者模式

时间:2024-04-29 12:21:24

观察者模式是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,其所有依赖者(观察者)都会收到通知并自动更新。在观察者模式中,主题(也称为可观察者或被观察者)维护着一组观察者,并在状态发生变化时通知它们。

  • 结构

    1. 主题对象:也称为被观察者或者可观察对象,它维护了一组观察者对象,并提供了添加、删除和通知观察者的方法。主题对象的状态发生变化时,会通知所有注册的观察者。
    2. 观察者对象:观察者对象通过注册到主题对象上,以便在主题状态变化时接收通知。观察者对象通常定义了一个更新方法,用于接收主题对象发出的通知,并作出相应的更新。
    3. 一对多的依赖关系:观察者模式建立了一种一对多的依赖关系,一个主题对象可以有多个观察者对象,而每个观察者对象都只依赖于一个主题对象。
    4. 解耦:观察者模式将主题对象与观察者对象之间解耦,使得它们可以独立变化,而不会相互影响。这样可以降低系统的耦合度,提高代码的灵活性和可维护性。
    5. 动态变化:观察者模式允许动态地添加或删除观察者对象,而不需要修改主题对象的代码,使得系统更加灵活和可扩展。
  • 优点

    1. 解耦:观察者模式将主题对象与观察者对象之间解耦,使得它们可以独立变化,而不会相互影响。
    2. 扩展性:可以随时添加或删除观察者对象,而不影响主题对象或其他观察者对象,使得系统更加灵活和可扩展。
    3. 通知机制:观察者模式提供了一种灵活的通知机制,可以实时地通知观察者对象主题状态的变化,从而实现更紧密的协作。
  • 缺点

    1. 过多通知:如果主题对象的状态变化频繁,可能会导致观察者对象频繁地收到通知,造成性能上的开销。
    2. 循环依赖:如果观察者对象之间相互依赖,可能会导致循环依赖的问题,需要谨慎设计。
  • 场景

    1. 事件处理:GUI编程中常用观察者模式处理用户界面组件的事件。
    2. 消息通知:发布/订阅模式是观察者模式的一种变体,常用于实现消息队列等系统。
    3. 状态监控:当需要监控对象的状态变化并作出相应响应时,观察者模式是一个常见的选择。
    4. 发布订阅系统:用于构建解耦的事件驱动架构,其中发布者和订阅者之间没有直接的依赖关系。
  • 示例

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

// 主题接口(Subject Interface)
interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers();
    int getState();
}

// 具体主题类(Concrete Subject Class)
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

// 观察者接口(Observer Interface)
interface Observer {
    void update();
}

// 具体观察者类(Concrete Observer Class)
class ConcreteObserver implements Observer {
    private Subject subject;

    public ConcreteObserver(Subject subject) {
        this.subject = subject;
    }

    public void update() {
        System.out.println("Observer received update. New state: " + subject.getState());
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        // 创建具体主题对象
        ConcreteSubject subject = new ConcreteSubject();

        // 创建具体观察者对象,并将主题对象注册为观察者
        ConcreteObserver observer = new ConcreteObserver(subject);
        subject.attach(observer);

        // 改变主题对象的状态
        subject.setState(10);

        // 取消观察者的注册
        subject.detach(observer);

        // 再次改变主题对象的状态
        subject.setState(20);
    }
}
  • 输出结果
Observer received update. New state: 10