技术
观察者模式
田敏
2024-11-272 分钟阅读Design PatternSoftware Engineering
参考链接:观察者模式 | 菜鸟教程 (runoob.com)
观察者模式
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
意图
创建了对象间的一种一对多的依赖关系,当一个对象状态改变时,所有依赖于它的对象都会得到通知并自动更新。
主要解决的问题
- 观察者模式解决的是一个对象状态改变时,如何自动通知其他依赖对象的问题,同时保持对象间的低耦合和高协作性。
使用场景
- 当一个对象的状态变化需要同时更新其他对象时。
实现方式
- 定义观察者接口:包含一个更新方法。
- 创建具体观察者:实现观察者接口,定义接收到通知时的行为。
- 定义主题接口:包含添加、删除和通知观察者的方法。
- 创建具体主题:实现主题接口,管理观察者列表,并在状态改变时通知它们。
实现
观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。
ObserverPatternDemo,我们的演示类使用 Subject 和实体类对象来演示观察者模式。

在.NET中的使用
在 .NET 中,观察者模式广泛用于处理事件驱动的应用程序、实时监控和跨组件通信等场景。以下是一些典型的应用场景:
1. 事件机制
- 场景:观察者模式直接体现在 .NET 事件机制中,利用
event关键字定义的事件可以让订阅者(观察者)注册以获取通知。 - 例子:
Button点击事件。在 WinForms 或 WPF 中,可以为一个按钮的Click事件添加多个事件处理程序,当按钮被点击时通知所有处理程序。 - 代码示例:
Button button = new Button(); button.Click += (sender, e) => Console.WriteLine("Button clicked!");
2. 数据绑定和属性变更通知
- 场景:
INotifyPropertyChanged接口常用于 WPF 和 WinForms 应用程序的数据绑定。此接口允许对象属性变更后通知 UI 更新,从而实现数据绑定。 - 例子:MVVM 模式中的 ViewModel 层使用
INotifyPropertyChanged通知视图更新。 - 代码示例:
public class Person : INotifyPropertyChanged { private string name; public string Name { get => name; set { if (name != value) { name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); } } } public event PropertyChangedEventHandler PropertyChanged; }
3. 文件系统监控(FileSystemWatcher)
- 场景:
FileSystemWatcher类用于监控文件或目录的变化,并通知订阅者文件是否创建、修改、删除或重命名。 - 例子:实现文件夹或文件变更监听的系统。
- 代码示例:
FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Path = @"C:\temp"; watcher.Changed += (sender, e) => Console.WriteLine($"File {e.FullPath} was changed"); watcher.EnableRaisingEvents = true;
4. 观察者模式在 Rx.NET(Reactive Extensions)中的实现
- 场景:使用观察者模式处理流式数据。通过
IObservable<T>和IObserver<T>接口,Rx.NET 提供了大量支持异步和事件驱动的数据流处理。 - 例子:实时数据流处理,比如股票数据监控。
- 代码示例:
IObservable<int> numbers = Observable.Range(1, 10); numbers.Subscribe( x => Console.WriteLine($"Received {x}"), ex => Console.WriteLine($"Error: {ex.Message}"), () => Console.WriteLine("Completed"));
5. ASP.NET 中的信号通知和广播
- 场景:在 ASP.NET Core SignalR 中,观察者模式用于实现实时通信。客户端可以订阅特定的通知,服务器在有更新时广播消息,所有订阅的客户端会收到该更新。
- 例子:即时聊天应用、股票价格实时更新。
- 代码示例:
// 定义一个 Hub public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } }
6. 日志订阅系统
- 场景:应用程序可以将多个日志观察者(如文件、数据库、控制台)注册到日志服务中。日志服务在记录日志时会通知所有观察者。
- 例子:通过依赖注入注册多种日志提供程序,方便扩展和统一管理日志记录。
- 代码示例:
public class Logger { private readonly List<ILogObserver> _observers = new List<ILogObserver>(); public void RegisterObserver(ILogObserver observer) => _observers.Add(observer); public void Log(string message) { foreach (var observer in _observers) { observer.Update(message); } } }
总结
在 .NET 中,观察者模式提供了基于事件的松耦合设计,适用于实现通知广播、多订阅和异步更新等场景。无论是在 UI 数据绑定、文件系统监听,还是在事件驱动的数据流处理中,观察者模式都提供了简便的解决方案,使组件间通信更高效。
版权协议:MIT返回列表