C# 一分钟浅谈:观察者模式与订阅发布模式

简介: 【10月更文挑战第11天】本文介绍了观察者模式和订阅发布模式,这两种设计模式主要用于实现对象间的解耦。观察者模式通过事件和委托实现一个对象状态改变时通知多个依赖对象;订阅发布模式则通过事件聚合器实现发布者与订阅者之间的解耦。文章详细探讨了这两种模式的实现方式、常见问题及避免方法,帮助开发者在实际项目中更好地应用这些模式,提升代码的可维护性和扩展性。

在软件设计模式中,观察者模式和订阅发布模式是非常常见的两种模式,它们主要用于实现对象之间的解耦,使得一个对象的状态改变可以通知到其他依赖它的对象。本文将从概念入手,逐步深入探讨这两种模式的实现方式、常见问题以及如何避免易错点。
image.png

观察者模式

概念

观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式特别适用于“广播”类型的通知机制,即一个对象的改变需要通知多个其他对象。

实现

在C#中,可以通过事件(event)和委托(delegate)来实现观察者模式。下面是一个简单的示例:

using System;

// 定义一个委托
public delegate void NotifyEventHandler(string message);

// 被观察者类
public class Subject
{
   
    // 声明一个事件
    public event NotifyEventHandler NotifyEvent;

    // 当状态改变时触发事件
    public void ChangeState()
    {
   
        Console.WriteLine("Subject: 我的状态改变了!");
        NotifyEvent?.Invoke("状态已改变");
    }
}

// 观察者类
public class Observer
{
   
    // 注册事件处理方法
    public void OnNotify(string message)
    {
   
        Console.WriteLine($"Observer: 收到通知 - {message}");
    }
}

class Program
{
   
    static void Main(string[] args)
    {
   
        // 创建被观察者对象
        Subject subject = new Subject();

        // 创建观察者对象
        Observer observer = new Observer();

        // 订阅事件
        subject.NotifyEvent += observer.OnNotify;

        // 触发状态改变
        subject.ChangeState();

        // 取消订阅
        subject.NotifyEvent -= observer.OnNotify;
    }
}

常见问题及避免

  1. 内存泄漏:如果观察者没有及时取消订阅,可能会导致内存泄漏。确保在不再需要通知时取消订阅。
  2. 线程安全:在多线程环境中,事件的调用可能会引发线程安全问题。可以使用锁或其他同步机制来保证线程安全。
  3. 性能问题:如果观察者的数量很多,频繁触发事件可能会导致性能下降。可以通过批量通知或异步通知来优化。

订阅发布模式

概念

订阅发布模式(Pub/Sub)是一种消息传递模式,其中发送者(发布者)不会将消息直接发送给特定的接收者(订阅者),而是将消息发布到一个主题或消息队列上,所有订阅了该主题的接收者都会收到消息。这种方式进一步解耦了发布者和订阅者之间的依赖关系。

实现

在C#中,可以使用EventAggregator(事件聚合器)来实现订阅发布模式。以下是一个简单的示例:

using System;
using Prism.Events;

// 定义一个事件
public class StateChangedEvent : PubSubEvent<string> {
    }

// 发布者类
public class Publisher
{
   
    private readonly IEventAggregator _eventAggregator;

    public Publisher(IEventAggregator eventAggregator)
    {
   
        _eventAggregator = eventAggregator;
    }

    public void PublishStateChange()
    {
   
        Console.WriteLine("Publisher: 发布状态改变通知");
        _eventAggregator.GetEvent<StateChangedEvent>().Publish("状态已改变");
    }
}

// 订阅者类
public class Subscriber
{
   
    private readonly IEventAggregator _eventAggregator;

    public Subscriber(IEventAggregator eventAggregator)
    {
   
        _eventAggregator = eventAggregator;
        _eventAggregator.GetEvent<StateChangedEvent>().Subscribe(OnStateChanged);
    }

    private void OnStateChanged(string message)
    {
   
        Console.WriteLine($"Subscriber: 收到通知 - {message}");
    }
}

class Program
{
   
    static void Main(string[] args)
    {
   
        // 创建事件聚合器
        IEventAggregator eventAggregator = new EventAggregator();

        // 创建发布者和订阅者
        Publisher publisher = new Publisher(eventAggregator);
        Subscriber subscriber = new Subscriber(eventAggregator);

        // 发布状态改变
        publisher.PublishStateChange();
    }
}

常见问题及避免

  1. 内存泄漏:订阅者如果没有及时取消订阅,可能会导致内存泄漏。确保在不再需要通知时取消订阅。
  2. 消息顺序:在某些情况下,消息的顺序可能很重要。确保消息队列支持有序消息传递。
  3. 性能问题:如果订阅者的数量很多,频繁发布消息可能会导致性能下降。可以通过批量发布或异步发布来优化。

总结

观察者模式和订阅发布模式都是用于实现对象之间解耦的设计模式。观察者模式通过事件和委托实现一对一或多对一的通知机制,而订阅发布模式通过事件聚合器实现一对多的通知机制。在实际开发中,合理选择和使用这些模式可以提高代码的可维护性和扩展性。同时,注意避免内存泄漏、线程安全和性能问题,确保系统的稳定性和高效性。

目录
相关文章
|
设计模式 C#
c#设计模式-行为型模式 之 观察者模式
又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者 对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自 动更新自己。
49 1
|
设计模式 监控 C#
⭐️C#零基础到入门 ⭐️| 编程 设计模式界的”网红”——观察者模式
前言 前边有一篇文章简单介绍了23中设计模式和六大设计原则。原文///C#进阶知识学习 之 ☀️ 带你认识编程中的—23种设计模式 & 六大设计原则 在这里就挑几种常用的设计模式来做一个单独的详情介绍 ,就比如本篇文章的主角——观察者模式
⭐️C#零基础到入门 ⭐️| 编程 设计模式界的”网红”——观察者模式
|
C#
使用C# (.NET Core) 实现观察者模式 (Observer Pattern) 并介绍 delegate 和 event
观察者模式 这里面综合了几本书的资料. 需求 有这么个项目:  需求是这样的: 一个气象站, 有三个传感器(温度, 湿度, 气压), 有一个WeatherData对象, 它能从气象站获得这三个数据.
1963 0
|
C#
C#设计模式之十六观察者模式(Observer Pattern)【行为型】
原文:C#设计模式之十六观察者模式(Observer Pattern)【行为型】 一、引言   今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西。
1411 0
C# 观察者模式.
原文地址:这里写链接内容 $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length;
992 0
C#设计模式---观察者模式简单例子
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/38169159 在...
747 0
|
XML SQL C#
乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:webabcd 介绍 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。
788 0
|
11天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
24 3
|
1月前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。