观察者模式(Observer Pattern)
观察者模式(Observer Pattern)
定义
观察者模式(Observer Pattern) 是一种行为设计模式,允许对象(称为 Subject,主题)维护一组依赖对象(称为 Observer,观察者),并在主题状态变化时自动通知所有观察者。其核心是 一对多的依赖关系 和 事件驱动的通信机制。
核心思想
-
解耦主题与观察者:主题无需知道观察者的具体实现,只需通过接口通知。
-
动态订阅机制:观察者可随时注册或注销对主题的监听。
-
自动广播通知:主题状态变化时,自动触发所有观察者的响应逻辑。
模式结构
-
抽象主题(Subject):定义注册、移除观察者的接口,维护观察者列表,在状态变化时触发通知。作为被观察对象的核心抽象,通过接口规范观察者管理行为。
-
具体主题类(ConcreteSubject):实现抽象主题接口,存储具体状态数据,状态变更时调用通知方法,是状态的实际持有者。
-
观察者接口(IObserver):定义接收主题通知的更新方法, 解耦主题与观察者的关键,确保观察者实现统一的更新逻辑。
-
具体观察者类(ConcreteObserver):实现观察者接口,定义自身对主题状态变化的响应逻辑(如更新显示、记录日志),实现业务场景中的具体响应。
主要解决的问题
-
对象间实时更新:当对象状态变化时,依赖它的多个对象需同步更新(如 GUI 组件)。
-
避免紧耦合:减少主题与观察者的直接依赖,提升代码复用性和扩展性
-
替代轮询机制:通过事件驱动避免资源浪费,仅在状态变化时触发更新。
代码示例
场景描述
假设一个气象站(WeatherStation)作为主题,当温度变化时,自动通知显示屏(Display)和移动应用(MobileApp)更新显示。
实现代码
using System;
using System.Collections.Generic;
// 主题接口
interface ISubject
{
void RegisterObserver(IObserver observer);
void RemoveObserver(IObserver observer);
void NotifyObservers();
}
// 观察者接口
interface IObserver
{
void Update(float temperature);
}
// 具体主题:气象站
class WeatherStation : ISubject
{
public event Action<float>? OnTemperatureChanged;
private float _temperature;
public void RegisterObserver(IObserver observer)
{
OnTemperatureChanged += observer.Update;
}
public void RemoveObserver(IObserver observer)
{
OnTemperatureChanged -= observer.Update;
}
public void NotifyObservers()
{
OnTemperatureChanged?.Invoke(Temperature);
}
public float Temperature
{
get => _temperature;
set
{
_temperature = value;
NotifyObservers(); // 温度变化时触发通知
}
}
}
// 具体观察者:显示屏
class Display : IObserver
{
public void Update(float temperature) =>
Console.WriteLine($"显示屏更新:当前温度 {temperature}°C");
}
// 具体观察者:移动应用
class MobileApp : IObserver
{
public void Update(float temperature) =>
Console.WriteLine($"移动应用推送:气温已变为 {temperature}°C");
}
// 客户端调用
class Program
{
static void Main()
{
WeatherStation station = new WeatherStation();
Display display = new Display();
MobileApp app = new MobileApp();
// 注册观察者
station.RegisterObserver(display);
station.RegisterObserver(app);
// 模拟温度变化
station.Temperature = 25.5f;
station.Temperature = 26.0f;
// 移除一个观察者
station.RemoveObserver(app);
station.Temperature = 27.3f;
}
}
输出结果
显示屏更新:当前温度 25.5°C
移动应用推送:气温已变为 25.5°C
显示屏更新:当前温度 26°C
移动应用推送:气温已变为 26°C
显示屏更新:当前温度 27.3°C
总结
优点
-
解耦性强:主题与观察者通过接口交互,互不影响内部实现。
-
动态扩展:新增观察者无需修改主题代码,符合开闭原则。
-
事件驱动高效:仅在状态变化时触发更新,避免资源浪费。
缺点
-
通知顺序不可控:观察者响应顺序可能影响系统行为。
-
循环引用风险:若观察者持有主题引用且未正确注销,可能导致内存泄漏。
通过观察者模式,C# 开发者可以构建灵活、可维护的事件驱动系统,广泛应用于 GUI 框架、消息队列、实时数据同步等场景。

浙公网安备 33010602011771号