C# 观察者模式

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

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

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

  1. IObservable<T> 和 IObserver<T> 接口

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

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

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

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

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

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

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

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

// 定义通知接口(也可以使用现有的 INotifyPropertyChanged, IObservable<T>)
public interface INotification
{
    void Notify(string message);
}

// 被观察者实现
public class Publisher : INotification
{
    private List<IObserver<string>> _observers = new List<IObserver<string>>();

    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()
    {
        // 清理或完成相关工作
    }
}

 

 

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

C# delegate的使用

 

定义一个被观察的主题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类在创建时订阅了这个事件,并定义了一个方法来处理这个事件。

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

 

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

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

 

 

相关推荐

  1. C# 观察模式

    2024-03-14 07:24:09       51 阅读
  2. 观察模式-C#

    2024-03-14 07:24:09       27 阅读
  3. [C/C++] -- 观察模式

    2024-03-14 07:24:09       33 阅读
  4. c#观察设计模式

    2024-03-14 07:24:09       55 阅读
  5. C++ 设计模式观察模式

    2024-03-14 07:24:09       51 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-14 07:24:09       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-14 07:24:09       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-14 07:24:09       82 阅读
  4. Python语言-面向对象

    2024-03-14 07:24:09       91 阅读

热门阅读

  1. python如何做数据分析

    2024-03-14 07:24:09       46 阅读
  2. 一文读懂回流(重排)重绘

    2024-03-14 07:24:09       39 阅读
  3. Android Selinux详解[四]--新增服务标签相关

    2024-03-14 07:24:09       38 阅读
  4. Kotlin初级【基本语法、数据类型、循环】

    2024-03-14 07:24:09       41 阅读
  5. Docker 搭建 Nacos 集群教程

    2024-03-14 07:24:09       41 阅读
  6. React——关于react概述

    2024-03-14 07:24:09       42 阅读
  7. React几种避免子组件无效刷新的方案

    2024-03-14 07:24:09       38 阅读
  8. spring cloud负载均衡算法,类型

    2024-03-14 07:24:09       39 阅读
  9. Element-UI穿梭框去掉左箭头按钮

    2024-03-14 07:24:09       34 阅读
  10. 信号和槽1

    2024-03-14 07:24:09       38 阅读
  11. sql server 生成本月日期的临时表

    2024-03-14 07:24:09       42 阅读