Java接口是实现观察者模式最自然、最解耦的方式,通过Subject和Observer接口分离职责,支持泛型、Lambda注册及不可变数据传递,避免继承限制与类型不安全问题。

Java接口是实现观察者模式最自然、最解耦的方式。它不依赖具体类,只靠契约约定行为,让主题(Subject)和观察者(Observer)彼此隔离,各自可独立演进。
定义清晰的接口契约
观察者模式的核心在于两个角色的职责分离,接口正是承载这种分离的最佳载体:
- Subject 接口:声明注册、移除、通知三个基础能力,不暴露内部状态或实现细节
- Observer 接口:只定义一个 update() 方法,参数根据业务需要灵活设计(如单个值、对象封装、或 void)
- 避免使用 Java 原生
java.util.Observer和java.util.Observable—— 它们已废弃多年,且 Observable 是类而非接口,限制继承,违背组合优于继承原则
用接口驱动具体实现
接口定义好后,具体类只需实现对应接口,无需强耦合:
- 具体主题(如
WeatherStation)实现Subject,内部维护List<Observer>,在状态变更时遍历调用observer.update(...) - 具体观察者(如
PhoneDisplay、MailAlert)实现Observer,专注自身响应逻辑,完全不知道谁在通知它 - 新增观察者(比如加个短信提醒模块)只需新写一个类实现
Observer,再调用subject.register(new SmsObserver())即可,零修改已有代码
支持泛型与类型安全
Java 接口可配合泛型增强表达力和安全性:
立即学习“Java免费学习笔记(深入)”;
- 定义
interface Observer<T> { void update(T data); },让不同主题传递不同类型的数据(Double表示价格、WeatherData对象表示气象信息) - 具体观察者实现时指定类型:
class PriceWatcher implements Observer<Double>,编译期就能检查参数类型是否匹配 - 避免传统
update(Object arg)方式带来的强制类型转换和运行时异常风险
结合现代 Java 特性提升灵活性
接口还可融合函数式编程思想,让观察者注册更轻量:
- 提供默认方法支持 Lambda 注册:
default void register(Consumer<Double> handler) { ... },允许直接传入price -> System.out.println("Price changed to: " + price) - 用
Function或BiConsumer替代固定 update 签名,适配不同数据维度(温度+湿度+气压三元组可用BiConsumer<Double, Double>拆分处理) - 配合 Optional 或 record 类型传递不可变通知数据,保障线程安全与语义清晰


















