1. jdk原生的观察者模式过时了
在 JDK 中,观察者模式的相关接口和类是 java.util.Observer
和 java.util.Observable
,它们从 JDK 9 开始被标记为 @Deprecated
,但并未被彻底移除。以下是被标记为过时的原因以及如何替代它们。
为什么 Observer
和 Observable
被标记为过时?
- 不符合现代设计理念:
Observable
是一个类,而不是接口,这限制了扩展性。- 现代设计更倾向于通过接口来定义行为,使得类可以自由组合多个功能,而不是被强制继承一个具体的实现。
- 线程安全问题:
Observable
的方法没有明确的线程安全保证,特别是在多线程环境中操作Observable
时可能会导致并发问题,例如在添加或删除观察者时。
- 不够灵活:
Observable
的实现过于简单,难以满足复杂的需求。例如,它不支持细粒度的通知机制,也无法方便地处理特定的订阅者群体。
- 与流式 API 和响应式编程的不兼容:
- JDK 自从引入了
java.util.stream
和响应式框架(如java.util.concurrent.Flow
),提供了更强大、更现代的方式来实现观察者模式。这些方式更灵活,且与其他现代 API 更兼容。
- JDK 自从引入了
有没有被废除?
虽然 Observer
和 Observable
被标记为过时(@Deprecated
),但它们依然存在于 JDK 中,并未被彻底移除。这意味着现有的代码仍然可以使用它们,但建议避免在新代码中继续使用。
替代方案
- 使用
java.util.concurrent.Flow
从 JDK 9 开始,Java 提供了java.util.concurrent.Flow
类来支持响应式流(Reactive Streams),这是实现观察者模式的现代方式。它包含以下主要接口:Flow.Publisher
Flow.Subscriber
Flow.Processor
示例:
import java.util.concurrent.Flow; import java.util.concurrent.SubmissionPublisher; public class ObserverExample { public static void main(String[] args) throws InterruptedException { SubmissionPublisher<String> publisher = new SubmissionPublisher<>(); Flow.Subscriber<String> subscriber = new Flow.Subscriber<>() { private Flow.Subscription subscription; @Override public void onSubscribe(Flow.Subscription subscription) { this.subscription = subscription; subscription.request(1); } @Override public void onNext(String item) { System.out.println("Received: " + item); subscription.request(1); } @Override public void onError(Throwable throwable) { System.err.println("Error: " + throwable.getMessage()); } @Override public void onComplete() { System.out.println("Done"); } }; publisher.subscribe(subscriber); publisher.submit("Hello"); publisher.submit("World"); publisher.close(); Thread.sleep(100); // 等待订阅者处理完毕 } }
- 使用第三方库(如 RxJava 或 Project Reactor)
如果需要更强大的响应式编程功能,可以使用第三方库:- RxJava:流行的响应式扩展库。
- Project Reactor:Spring 框架的响应式编程核心库。
- 手动实现观察者模式
可以根据项目需求手动实现一个简单而灵活的观察者模式。import java.util.ArrayList; import java.util.List; interface Observer { void update(String message); } 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); } public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } } public class CustomObserverExample { public static void main(String[] args) { Subject subject = new Subject(); Observer observer1 = msg -> System.out.println("Observer 1 received: " + msg); Observer observer2 = msg -> System.out.println("Observer 2 received: " + msg); subject.addObserver(observer1); subject.addObserver(observer2); subject.notifyObservers("Hello Observers!"); } }
总结
虽然 java.util.Observer
和 java.util.Observable
并未被彻底移除,但它们已经过时,主要因为它们设计不灵活、缺乏线程安全性以及无法适应现代编程需求。在新项目中,推荐使用 Flow
API 或响应式编程框架(如 RxJava 或 Reactor)来实现观察者模式。
文档信息
- 本文作者:Marshall