观察者(Observer、Publish-Subscribe:Pub/Sub)模式属于行为型模式的一种。
观察者模式是一种一对多的通知机制,让发送通知的一方(被观察者)和接收通知的一方(观察者)能彼此分离,互不影响。观察者模式的目的是要分离被观察者和观察者之间的耦合关系。
观察者模式的核心在于建立一种机制,使得当一个对象的状态变化时,所有依赖于它的对象(观察者)都能得到通知并作出相应的更新。
广义的观察者模式包括所有消息系统。消息系统,就是把观察者和被观察者完全分离,通过消息系统本身来进行通知。
在真实世界中,出版社是发布者,我们这些订阅了报纸或杂志的民众,是订阅者。出版社会在刊物出版后直接将最新一期寄送给我们,我们不用跑去出版社拿了。
Java标准库中的 java.util.Observer 类和 java.util.Observable 类,本来可以用来帮助我们实现观察者模式的。但是,这两个类在Java 9中已经被弃用了,弃用原因我就不描述了,大家可以搜一下。我们可以使用自定义的观察者模式,来满足更灵活的需求。
观察者模式通常有以下组成部分:
- 观察者接口:包含一个更新方法,用于接收主题的通知。
- 具体观察者:实现观察者接口,定义接收到通知时的行为。
- 主题接口:包含添加、删除和通知观察者的方法。
- 具体主题:实现主题接口,管理观察者列表,并在状态改变时通知它们。
我们模拟一个简单的观察者模式。
1、观察者接口
java
// 观察者接口
public interface Observer {
void update(String message); }

2、具体观察者
java
// 具体观察者
public class ConcreteObserver implements Observer { private String name; public ConcreteObserver(String name) { this.name = name; } @Override public void update(String message) { System.out.println(name + " received message: " + message); } }

3、主题接口
java
// 主题接口
public interface Subject {
void addObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(String message); }

4、具体主题
java
// 具体主题
public class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<>(); @Override public void addObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } }

5、客户端
java
// 客户端代码
public class ObserverPatternDemo {
public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); Observer observer1 = new ConcreteObserver("Observer 1"); Observer observer2 = new ConcreteObserver("Observer 2"); subject.addObserver(observer1); subject.addObserver(observer2); subject.notifyObservers("Hello Observers!"); } }

观察者模式的优缺点。
优点:
- 降低耦合度:主题和观察者之间是抽象耦合的,彼此独立,易于维护和扩展。
- 动态添加和删除观察者:可以在运行时动态地添加或删除观察者,灵活性高。
缺点:
- 性能问题:如果观察者数量众多,通知过程可能耗时,影响性能。
- 可能导致循环依赖:不当的设计可能导致观察者和主题之间的循环依赖,造成内存泄漏。
观察者模式是一种强大的设计模式,能够有效地解耦对象之间的关系,适用于需要在对象状态变化时通知多个依赖对象的场景。
怨天者无志,怨人者心穷。-- 烟沙九洲