在C#中,观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有注册过的观察者对象,使它们能够自动更新自己。
观察者模式的主要组成
-
主题(Subject):也称为被观察者,它持有观察者对象的列表,并管理这些观察者的注册和注销操作。当主题对象的状态发生变化时,它会遍历观察者列表,通知所有的观察者。
-
观察者(Observer):定义了一个更新接口,使得在得到主题的通知时更新自己。这个接口是一个抽象类或接口,具体观察者需要实现这个接口。
-
具体主题(Concrete Subject):实现了主题接口,用于存储和管理观察者对象列表,并在状态变化时通知所有观察者。
-
具体观察者(Concrete Observer):实现了观察者接口,并实现了更新方法,以便在接收到通知时执行具体的更新操作。
示例代码
下面是一个简单的C#观察者模式示例,用于模拟天气预报系统的更新。
csharp复制代码
using System; | |
using System.Collections.Generic; | |
// 抽象主题(Subject) | |
public abstract class Subject | |
{ | |
private List<Observer> observers = new List<Observer>(); | |
// 注册观察者 | |
public void RegisterObserver(Observer o) | |
{ | |
observers.Add(o); | |
} | |
// 移除观察者 | |
public void RemoveObserver(Observer o) | |
{ | |
observers.Remove(o); | |
} | |
// 通知所有观察者 | |
public void Notify(string message) | |
{ | |
foreach (Observer observer in observers) | |
{ | |
observer.Update(message); | |
} | |
} | |
} | |
// 抽象观察者(Observer) | |
public interface Observer | |
{ | |
void Update(string message); | |
} | |
// 具体主题(Concrete Subject) | |
public class WeatherData : Subject | |
{ | |
private string temperature; | |
private string humidity; | |
private string pressure; | |
// 天气数据更新时,通知所有观察者 | |
public void MeasurementsChanged() | |
{ | |
Notify($"Temperature: {temperature}, Humidity: {humidity}, Pressure: {pressure}"); | |
} | |
// 设置温度并通知 | |
public void SetMeasurements(string temperature, string humidity, string pressure) | |
{ | |
this.temperature = temperature; | |
this.humidity = humidity; | |
this.pressure = pressure; | |
MeasurementsChanged(); | |
} | |
} | |
// 具体观察者(Concrete Observer) | |
public class CurrentConditionsDisplay : Observer | |
{ | |
public void Update(string message) | |
{ | |
Console.WriteLine("Current conditions: " + message); | |
} | |
} | |
// 客户端代码 | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
WeatherData weatherData = new WeatherData(); | |
CurrentConditionsDisplay display = new CurrentConditionsDisplay(); | |
weatherData.RegisterObserver(display); | |
// 更新天气数据 | |
weatherData.SetMeasurements("22.5 degrees C", "65%", "30.4 inches"); | |
} | |
} |
在这个示例中,WeatherData
类是一个具体主题,它维护了一个观察者列表,并在天气数据更新时通知所有注册的观察者。CurrentConditionsDisplay
类是一个具体观察者,它实现了Observer
接口,并在接收到通知时更新显示天气信息。
优点
- 观察者模式实现了表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,有利于减少模块间的耦合。
- 它支持广播通信,当主题对象状态发生变化时,会通知所有注册的观察者对象,使它们能够自动更新。
缺点
- 如果一个主题对象有很多观察者对象,那么将通知到所有的观察者对象会花费很多时间。
- 如果在主题对象的状态发生变化时,需要同时更新很多个观察者对象,并且每个观察者对象的更新都非常复杂,那么这可能会导致系统效率降低。
- 如果使用不当,可能会导致更新数据的“泛滥”,即无用的更新信息发送给观察者对象。