Skip to main content

观察者模式

设计模式观察者模式About 2 min

观察者模式为组件向相关接收方广播消息提供了灵活的方法。该模式定义了对象间一到多的依赖关系,这样当对象改变状态时,将自动通知并更新它所有的依赖对象。

20240211160606

观察者模式角色:

  1. 抽象主题(Subject):也称为抽象目标类。这个角色定义了观察者和被观察者之间的接口,它通常包含以下方法:

addObserver(Observer observer):添加一个观察者到订阅列表中。
removeObserver(Observer observer):从订阅列表中移除一个观察者。
notifyObservers()notifyObservers(Datatype update):通知所有已注册的观察者对象更新状态,有时候会携带更新的数据。
2. 具体主题(ConcreteSubject):实现了抽象主题的类,它在内部状态改变时负责通知所有已注册的观察者。
3. 抽象观察者(Observer):定义了一个接口,该接口使得观察者可以了解主题对象的任何状态变化,并提供相应的方法来更新自己。通常包含:
update() 方法,当主题对象的状态发生改变时调用此方法来更新观察者的状态。
4. 具体观察者(ConcreteObserver):实现了抽象观察者接口的类,存储对主题对象的引用并实现具体的更新逻辑,在接收到主题的通知后更新自身的状态。

代码实现

抽象主题

抽象主题中,管理所有要通知的观察者集合,并提供notifyObservers方法进行遍历通知。

public abstract class Subject {
    private final List<Observer> observers = new ArrayList<>();

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

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

    protected void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

具体主题

具体主题需要在自身状态发生变化的时候,通知观察者。

public class ConcreteSubject extends Subject {

    private String message;

    public void setMessage(String message) {
        this.message = message;

        notifyObservers(message);
    }

    public String getMessage() {
        return message;
    }
}

抽象观察者

public interface Observer {
    void update(String message);
}

具体观察者

public class ConcreteObserver implements Observer {

    @Override
    public void update(String message) {
        System.out.printf("%s: [%s]%n", this.getClass().getName(), message);
    }

}

使用

public class Client {

    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

        ConcreteObserver concreteObserver = new ConcreteObserver();

        subject.addObserver(concreteObserver);

        subject.setMessage("new messages");
    }
}


结果:

20240211164554

What do you think?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
Comments
  • Latest
  • Oldest
  • Hottest
Powered by Waline v3.0.0-alpha.10