**观察者模式(Observer Pattern)**是软件设计模式中的一种行为型模式,它定义了对象之间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会自动被通知并更新。观察者模式又被称为发布-订阅(Publish-Subscribe)模式、模型-视图(Model-View)模式、或者事件(Event)模型。

概述

观察者模式主要包含三个角色:

  • Subject(目标):被观察的对象,它维护一组观察者对象,提供用于增加和删除观察者对象的方法,并在自身状态改变时通知各个观察者。
  • Observer(观察者):观察者将自己注册到目标对象,当目标对象的状态发生变化时,会得到通知并执行相应的更新操作。
  • ConcreteSubject(具体目标):具体目标是目标类的子类,通常包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知。
  • ConcreteObserver(具体观察者):具体观察者是观察者的子类,实现了更新的方法,用于接收到目标的通知后采取相应的行动。

观察者模式的关键是在目标与观察者之间建立一种松耦合的关系,目标对象并不需要知道观察者的具体实现,只需要知道观察者对象实现了一个特定的接口或者抽象类即可。这样可以降低目标与观察者之间的耦合度,提高系统的扩展性和灵活性。

示例代码

为了更加直观地理解观察者模式,我们来看一个简单的示例,假设我们有一个主题(Subject)对象,它可以接受观察者(Observer)注册,并在状态变化时通知观察者更新。

首先,定义一个Subject接口,包含了注册、移除和通知观察者的方法:

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

然后,定义一个具体的主题类ConcreteSubject,实现Subject接口,并在状态变化时通知观察者:

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

public class ConcreteSubject implements Subject {

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

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

    public int getState() {
        return state;
    }

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

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

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

接下来,定义一个Observer接口,包含了接收通知并进行更新的方法:

public interface Observer {
    void update();
}

最后,我们可以定义一个具体的观察者类ConcreteObserver,实现Observer接口,并在接收到通知时进行更新操作:

public class ConcreteObserver implements Observer {

    private ConcreteSubject subject;

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

    @Override
    public void update() {
        int state = subject.getState();
        System.out.println("观察者收到通知,新状态为:" + state);
    }
}

现在,我们可以测试一下观察者模式的效果:

public class ObserverPatternDemo {

    public static void main(String[] args) {
        // 创建具体主题对象
        ConcreteSubject subject = new ConcreteSubject();

        // 创建具体观察者对象,并将主题对象注册到观察者中
        Observer observer1 = new ConcreteObserver(subject);
        Observer observer2 = new ConcreteObserver(subject);
        Observer observer3 = new ConcreteObserver(subject);
        subject.registerObserver(observer1);
        subject.registerObserver