观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
当主题对象状态发生改变时,它的所有依赖者(观察者)都会自动收到通知并更新。
IObservable
System.IObservable 和 System.IObserver 两个接口来标准化观察者模式的实现。IObservable 表示可发送通知的对象,而 IObserver 定义了接收这些通知的方法。IObserver 接口中包含三个方法:OnNext(T value)、OnError(Exception error) 和 OnCompleted(),分别用于接收到新的数据项、错误通知以及通知序列已完成。Subject 类:
IObservable 并实现其逻辑的类,比如 Subject 或 ReplaySubject(Rx.NET 库中),这个类负责维护订阅它的观察者的列表,并在适当的时候调用它们的方法。观察者实现:
IObserver 接口,这样当被观察者有状态变化时,可以通过 OnNext 等方法得到通知并执行相应的操作。注册与解除注册:
Subscribe(IObserver observer) )让观察者可以订阅事件,同时应有一个方法(如 Unsubscribe(IObserver observer) 或使用返回的 IDisposable 对象来取消订阅)来解除订阅。事件委托和EventHandler:
EventHandler 委托常用于表示事件处理程序,sender 参数扮演着被观察者角色,而 EventArgs 子类传递的状态信息则类似于通知的数据项。实例教程步骤概要:
使用时,订阅者会注册到发布者的观察者列表中,当发布者发布新数据时,所有已注册的订阅者都会收到通知并执行相应操作。
- // 定义通知接口(也可以使用现有的 INotifyPropertyChanged, IObservable
) - public interface INotification
- {
- void Notify(string message);
- }
-
- // 被观察者实现
- public class Publisher : INotification
- {
- private List
string>> _observers = new Liststring>>(); -
- public void RegisterObserver(IObserver<string> observer)
- {
- _observers.Add(observer);
- }
-
- public void UnregisterObserver(IObserver<string> observer)
- {
- _observers.Remove(observer);
- }
-
- public void PublishNewData(string data)
- {
- foreach (var observer in _observers)
- {
- observer.OnNext(data);
- }
- }
- }
-
- // 观察者实现
- public class Subscriber : IObserver<string>
- {
- public void OnNext(string value)
- {
- Console.WriteLine($"Subscriber received: {value}");
- }
-
- public void OnError(Exception error)
- {
- // 处理错误
- }
-
- public void OnCompleted()
- {
- // 清理或完成相关工作
- }
- }
Subject类- using System;
- using System.Collections.Generic;
-
- public class Subject
- {
- // 委托类型,表示观察者的行为
- public delegate void StateChangedHandler(string newState);
-
- // 事件,用于注册和注销观察者
- public event StateChangedHandler StateChanged;
-
- // 主题的状态
- private string _state;
-
- // 获取或设置主题的状态
- public string State
- {
- get => _state;
- set
- {
- _state = value;
- // 当状态改变时,通知所有观察者
- OnStateChanged();
- }
- }
-
- // 受保护的方法,用于触发事件
- protected virtual void OnStateChanged()
- {
- StateChanged?.Invoke(_state);
- }
-
- // 订阅事件的方法
- public void Subscribe(StateChangedHandler handler)
- {
- StateChanged += handler;
- }
-
- // 取消订阅事件的方法
- public void Unsubscribe(StateChangedHandler handler)
- {
- StateChanged -= handler;
- }
- }
Observer类- public class Observer
- {
- private string _name;
- private Subject _subject;
-
- public Observer(string name, Subject subject)
- {
- _name = name;
- _subject = subject;
- // 订阅主题的状态改变事件
- _subject.Subscribe(HandleStateChanged);
- }
-
- private void HandleStateChanged(string newState)
- {
- Console.WriteLine($"Observer {_name} received new state: {newState}");
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- // 创建主题
- Subject subject = new Subject();
-
- // 创建观察者并订阅主题事件
- Observer observer1 = new Observer("Observer1", subject);
- Observer observer2 = new Observer("Observer2", subject);
-
- // 改变主题状态,触发事件
- subject.State = "New State";
-
- // 等待用户输入,防止程序立即退出
- Console.ReadLine();
- }
- }
在这个例子中,Subject类有一个State属性,当它的值改变时,它会触发一个事件。
Observer类在创建时订阅了这个事件,并定义了一个方法来处理这个事件。
当Subject的State改变时,所有订阅了StateChanged事件的Observer对象都会收到通知,并调用它们自己的HandleStateChanged方法。
这就是观察者模式在C#中的基本实现。它允许主题和观察者之间保持松耦合,主题不需要知道具体有哪些观察者,而观察者也不需要知道主题的具体实现。
这提高了代码的可扩展性、可维护性和灵活性。