观察者模式(Observer Pattern)是一种行为设计模式,允许对象(观察者)订阅另一个对象(被观察者),并在被观察者状态变化时自动接收通知。以下是详细解释及在 .NET Core 中的实现示例。
模式结构
-
Subject (主题/被观察者)
维护观察者列表,提供注册、移除观察者的方法,并在状态变化时通知观察者。
-
Observer (观察者)
定义更新接口,用于接收主题的通知。
自定义实现示例
场景描述
气象站(WeatherStation
)作为被观察者,当温度更新时,自动通知所有注册的显示设备(如手机应用、网页仪表盘)。
1. 定义接口
// 观察者接口
public interface IObserver
{
void Update(float temperature);
}
// 被观察者接口
public interface ISubject
{
void RegisterObserver(IObserver observer);
void RemoveObserver(IObserver observer);
void NotifyObservers();
}
2. 实现被观察者(Subject)
public class WeatherStation : ISubject
{
private List<IObserver> _observers = new List<IObserver>();
private float _temperature;
public void RegisterObserver(IObserver observer)
{
_observers.Add(observer);
}
public void RemoveObserver(IObserver observer)
{
_observers.Remove(observer);
}
public void NotifyObservers()
{
foreach (var observer in _observers)
{
observer.Update(_temperature);
}
}
public void SetTemperature(float temperature)
{
_temperature = temperature;
NotifyObservers(); // 温度更新时通知观察者
}
}
3. 实现观察者(Observer)
// 手机应用显示
public class MobileApp : IObserver
{
public void Update(float temperature)
{
Console.WriteLine($"Mobile App: Temperature updated to {temperature}°C");
}
}
// 网页仪表盘显示
public class WebDashboard : IObserver
{
public void Update(float temperature)
{
Console.WriteLine($"Web Dashboard: Current temperature is {temperature}°C");
}
}
4. 使用示例
class Program
{
static void Main(string[] args)
{
var weatherStation = new WeatherStation();
var mobileApp = new MobileApp();
var webDashboard = new WebDashboard();
// 注册观察者
weatherStation.RegisterObserver(mobileApp);
weatherStation.RegisterObserver(webDashboard);
// 更新温度,触发通知
weatherStation.SetTemperature(25.5f);
// 输出:
// Mobile App: Temperature updated to 25.5°C
// Web Dashboard: Current temperature is 25.5°C
}
}
.NET Core 内置实现
.NET Core 提供了 IObservable<T>
和 IObserver<T>
接口,简化观察者模式的实现。
1. 实现被观察者(IObservable)
using System;
using System.Collections.Generic;
public class WeatherStation : IObservable<float>
{
private List<IObserver<float>> _observers = new List<IObserver<float>>();
private float _temperature;
public IDisposable Subscribe(IObserver<float> observer)
{
_observers.Add(observer);
return new Unsubscriber(_observers, observer);
}
private class Unsubscriber : IDisposable
{
private List<IObserver<float>> _observers;
private IObserver<float> _observer;
public Unsubscriber(List<IObserver<float>> observers, IObserver<float> observer)
{
_observers = observers;
_observer = observer;
}
public void Dispose()
{
if (_observers.Contains(_observer))
_observers.Remove(_observer);
}
}
public void SetTemperature(float temperature)
{
_temperature = temperature;
foreach (var observer in _observers)
{
observer.OnNext(_temperature);
}
}
}
2. 实现观察者(IObserver)
public class MobileApp : IObserver<float>
{
public void OnNext(float temperature)
{
Console.WriteLine($"Mobile App: Temperature updated to {temperature}°C");
}
public void OnError(Exception error)
{
Console.WriteLine($"Error: {error.Message}");
}
public void OnCompleted()
{
Console.WriteLine("Weather station has shut down.");
}
}
3. 使用示例
class Program
{
static void Main(string[] args)
{
var weatherStation = new WeatherStation();
var mobileApp = new MobileApp();
// 订阅观察者
var subscription = weatherStation.Subscribe(mobileApp);
// 更新温度
weatherStation.SetTemperature(30.0f);
// 取消订阅
subscription.Dispose();
}
}
模式优缺点
优点
- 解耦主题与观察者,遵循开放-封闭原则。
- 支持动态订阅和取消订阅。
缺点
- 观察者过多时可能影响性能。
- 需注意避免循环通知。
适用场景
- 事件驱动系统(如 GUI 按钮点击)。
- 实时数据监控(如股票价格、传感器数据)。
- 分布式系统的消息通知(如微服务间的状态同步)。
通过观察者模式,你可以轻松实现松耦合的对象间通信,而 .NET Core 的内置接口进一步简化了实现过程。