• C# 观察者模式


    观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。

    当主题对象状态发生改变时,它的所有依赖者(观察者)都会自动收到通知并更新。

    一、在 C# 中实现观察者模式通常涉及以下关键部分

    1. IObservable 和 IObserver 接口

      • .NET Framework 提供了 System.IObservable 和 System.IObserver 两个接口来标准化观察者模式的实现。IObservable 表示可发送通知的对象,而 IObserver 定义了接收这些通知的方法。
      • IObserver 接口中包含三个方法:OnNext(T value)OnError(Exception error) 和 OnCompleted(),分别用于接收到新的数据项、错误通知以及通知序列已完成。
    2. Subject 类

      • 往往会创建一个继承自 IObservable 并实现其逻辑的类,比如 Subject 或 ReplaySubject(Rx.NET 库中),这个类负责维护订阅它的观察者的列表,并在适当的时候调用它们的方法。
    3. 观察者实现

      • 观察者类需要实现 IObserver 接口,这样当被观察者有状态变化时,可以通过 OnNext 等方法得到通知并执行相应的操作。
    4. 注册与解除注册

      • 被观察者提供一个方法(如 Subscribe(IObserver observer))让观察者可以订阅事件,同时应有一个方法(如 Unsubscribe(IObserver observer) 或使用返回的 IDisposable 对象来取消订阅)来解除订阅。
    5. 事件委托和EventHandler

      • 在传统的 .NET 事件处理机制中,虽然不直接采用 IObservable/IObserver 接口,但观察者模式的概念体现在事件(Event)和委托(Delegate)上,其中 EventHandler 委托常用于表示事件处理程序,sender 参数扮演着被观察者角色,而 EventArgs 子类传递的状态信息则类似于通知的数据项。
    6. 实例教程步骤概要

      • 抽象出一个通知接口(或者直接使用现有框架提供的 Observable 接口)。
      • 观察者实现该接口以接收通知。
      • 被观察者维护一个观察者集合,并提供注册/取消注册的方法。
      • 当被观察者状态变化时,遍历观察者集合并调用它们的更新方法,从而触发所有观察者的响应。

    二、使用接口简单实现观察者模式

    使用时,订阅者会注册到发布者的观察者列表中,当发布者发布新数据时,所有已注册的订阅者都会收到通知并执行相应操作。

    1. // 定义通知接口(也可以使用现有的 INotifyPropertyChanged, IObservable
    2. public interface INotification
    3. {
    4. void Notify(string message);
    5. }
    6. // 被观察者实现
    7. public class Publisher : INotification
    8. {
    9. private Liststring>> _observers = new Liststring>>();
    10. public void RegisterObserver(IObserver<string> observer)
    11. {
    12. _observers.Add(observer);
    13. }
    14. public void UnregisterObserver(IObserver<string> observer)
    15. {
    16. _observers.Remove(observer);
    17. }
    18. public void PublishNewData(string data)
    19. {
    20. foreach (var observer in _observers)
    21. {
    22. observer.OnNext(data);
    23. }
    24. }
    25. }
    26. // 观察者实现
    27. public class Subscriber : IObserver<string>
    28. {
    29. public void OnNext(string value)
    30. {
    31. Console.WriteLine($"Subscriber received: {value}");
    32. }
    33. public void OnError(Exception error)
    34. {
    35. // 处理错误
    36. }
    37. public void OnCompleted()
    38. {
    39. // 清理或完成相关工作
    40. }
    41. }

     

     

    三、使用事件(Event)和委托(Delegate)来实现观察者模式

    C# delegate的使用

     

    定义一个被观察的主题Subject

    1. using System;
    2. using System.Collections.Generic;
    3. public class Subject
    4. {
    5. // 委托类型,表示观察者的行为
    6. public delegate void StateChangedHandler(string newState);
    7. // 事件,用于注册和注销观察者
    8. public event StateChangedHandler StateChanged;
    9. // 主题的状态
    10. private string _state;
    11. // 获取或设置主题的状态
    12. public string State
    13. {
    14. get => _state;
    15. set
    16. {
    17. _state = value;
    18. // 当状态改变时,通知所有观察者
    19. OnStateChanged();
    20. }
    21. }
    22. // 受保护的方法,用于触发事件
    23. protected virtual void OnStateChanged()
    24. {
    25. StateChanged?.Invoke(_state);
    26. }
    27. // 订阅事件的方法
    28. public void Subscribe(StateChangedHandler handler)
    29. {
    30. StateChanged += handler;
    31. }
    32. // 取消订阅事件的方法
    33. public void Unsubscribe(StateChangedHandler handler)
    34. {
    35. StateChanged -= handler;
    36. }
    37. }

    定义观察者Observer

    1. public class Observer
    2. {
    3. private string _name;
    4. private Subject _subject;
    5. public Observer(string name, Subject subject)
    6. {
    7. _name = name;
    8. _subject = subject;
    9. // 订阅主题的状态改变事件
    10. _subject.Subscribe(HandleStateChanged);
    11. }
    12. private void HandleStateChanged(string newState)
    13. {
    14. Console.WriteLine($"Observer {_name} received new state: {newState}");
    15. }
    16. }

    使用这些类

    1. class Program
    2. {
    3. static void Main(string[] args)
    4. {
    5. // 创建主题
    6. Subject subject = new Subject();
    7. // 创建观察者并订阅主题事件
    8. Observer observer1 = new Observer("Observer1", subject);
    9. Observer observer2 = new Observer("Observer2", subject);
    10. // 改变主题状态,触发事件
    11. subject.State = "New State";
    12. // 等待用户输入,防止程序立即退出
    13. Console.ReadLine();
    14. }
    15. }

    在这个例子中,Subject类有一个State属性,当它的值改变时,它会触发一个事件。

    Observer类在创建时订阅了这个事件,并定义了一个方法来处理这个事件。

    SubjectState改变时,所有订阅了StateChanged事件的Observer对象都会收到通知,并调用它们自己的HandleStateChanged方法。

     

    这就是观察者模式在C#中的基本实现。它允许主题和观察者之间保持松耦合,主题不需要知道具体有哪些观察者,而观察者也不需要知道主题的具体实现。

    这提高了代码的可扩展性、可维护性和灵活性。

     

     

  • 相关阅读:
    【2023年11月第四版教材】软考高项极限冲刺篇笔记(1)
    Bloom后处理效果
    【Java基础】TreeSet集合、自然排序、比较器排序、成绩排序及不重复随机数案例
    docker安装rocketMQ并测试
    第一章:最新版零基础学习 PYTHON 教程(第二节 - Python语言优势及应用)
    Docker启动失败:Failed at step LIMITS spawning /sbin/modprobe
    公共关系学知识点整理
    SAS|统计学实现
    如何利用AI技术优化独立站客服系统?听听专家怎么说!
    记一次SQL注入的收获
  • 原文地址:https://blog.csdn.net/wangnaisheng/article/details/136678356