首页 > 编程笔记 > Java笔记 阅读:2

观察者模式(Java实现,附带实例)

观察者模式有时也叫生产者-消费者模式(producer-customer pattern)。这也是一种在开发各类应用程序时都很常用的模式,属于经典的 GoF(Gang of Four)设计模式。

这个模式用来描述两种对象之间的直接联系:
如果受观察的对象改变了它的状态,那么所有已经注册的客户(也就是刚才提到的观察者)都会得到通知。换句话说,发生在受观察者身上的任何状态变化都会通知给观察者。

观察者模式属于那种同时出现在多个 JDK 模块里的模式。其中一个地方是 java.base 模块的 java.util 包,这个包中含有名为 Observer 的接口。该接口已经弃用,但你依然可以发现有其他一些类型(例如,Observable 类)用到了它。

观察者模式实例演示

我们以车辆里不同位置的温度控制为例来演示观察者模式的用法。

假设有下面这样一个 VehicleSystem 系统,它每次变更其状态时都会通知相关各方,使得车中的各个地点(或者说,各个子系统)都能把各自的温度调整到与该状态相符的水平(参见下面的范例)。

【实例】每个子系统都会根据全局设置调整其自身的温度。
public static void main(String[] args) {
    System.out.println("Observer Pattern, vehicle temperature sensors");
    var temperatureControlSystem = new VehicleSystem();
    new CockpitObserver(temperatureControlSystem);
    new EngineObserver(temperatureControlSystem);

    temperatureControlSystem.setState("low");
}
程序输出结果如下:

Observer Pattern, vehicle temperature sensors
CockpitObserver, temperature:'11'
EngineObserver, temperature:'4'

我们设计的这个 SystemObserver 抽象类,利用 Java 语言的密封机制来限定该程序所支持的观察者(或者说,限定该程序所支持的子系统)。

另外,这个抽象类还提供一套基本的模板,让用户能够根据这套模板更为便捷地构建各个子系统(参见下面的实例)。

【实例】新添加的子系统必须按照我们设计的通用模板来编写,这样能够让代码更容易维护。
sealed abstract class SystemObserver permits CockpitObserver, EngineObserver {
    protected final VehicleSystem system;

    public SystemObserver(VehicleSystem system) {
        this.system = system;
    }

    abstract void update();
}
每个子系统的实例都含有一个指向主系统(即 VehicleSystem)的引用,这些子系统在初始化的过程中会把自己注册成主系统的一个观察者,当主系统改变其状态(也就是切换其温度挡位时),这些子系统都会得到通知。于是,每个子系统就会按照自己在这一挡位下应该维持的温度来调整自身(参见下图)。


图 1 用 UML 类图来演示主系统与观察该系统状态的各个子系统之间的关系

总结

观察者模式是一种强大的设计模式,它让相关各方都能得知系统的状态变化情况,而且无须关注或操纵系统的实现细节。

观察者模式模式让我们能够在应用程序运行期间,通过观察者对象的逻辑对各种处理流程做出配置,并让这些观察者能够得到适当的封装,解耦观察者与受观察者的逻辑。

相关文章