”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > C# |理解观察者模式

C# |理解观察者模式

发布于2024-07-30
浏览:225

C# | Understanding the Observer Pattern

笔记
您可以查看我个人网站上的其他帖子:https://hbolajraf.net

观察者模式是一种行为设计模式,其中一个对象(称为主体)维护其依赖项(称为观察者)的列表,并通常通过调用其中一个方法来通知它们任何状态更改。这种模式促进了对象之间的松散耦合,因为观察者只知道主题而不知道彼此。在 C# 中,这种模式通常用于事件驱动编程。

执行

让我们通过一个C#的详细示例来了解观察者模式。

主题界面

首先,我们为主题定义一个接口。该接口将包含注册、取消注册和通知观察者的方法。

public interface ISubject
{
    void RegisterObserver(IObserver observer);
    void UnregisterObserver(IObserver observer);
    void NotifyObservers();
}

观察者界面

接下来,我们为观察者定义一个接口。该接口将包含一个方法,当主体需要通知观察者时将调用该方法。

public interface IObserver
{
    void Update();
}

具体主题

现在,让我们实现一个实现 ISubject 接口的具体主题类。

public class ConcreteSubject : ISubject
{
    private List observers = new List();

    public void RegisterObserver(IObserver observer)
    {
        observers.Add(observer);
    }

    public void UnregisterObserver(IObserver observer)
    {
        observers.Remove(observer);
    }

    public void NotifyObservers()
    {
        foreach (var observer in observers)
        {
            observer.Update();
        }
    }
}

具体观察者

接下来,让我们实现一个具体的观察者类,该类实现了 IObserver 接口。

public class ConcreteObserver : IObserver
{
    public void Update()
    {
        Console.WriteLine("Observer notified of state change.");
    }
}

用法示例

现在,让我们看看如何一起使用这些类。

class Program
{
    static void Main(string[] args)
    {
        ConcreteSubject subject = new ConcreteSubject();
        ConcreteObserver observer1 = new ConcreteObserver();
        ConcreteObserver observer2 = new ConcreteObserver();

        subject.RegisterObserver(observer1);
        subject.RegisterObserver(observer2);

        subject.NotifyObservers();

        subject.UnregisterObserver(observer1);

        subject.NotifyObservers();
    }
}

在这个例子中,ConcreteSubject是主体,ConcreteObserver是观察者。当调用 NotifyObservers() 时,两个观察者都会收到状态更改的通知。注销一名观察员后,仅通知剩余的观察员。

接下来是什么?

观察者模式是在 C# 中实现对象之间通信的强大方法。它促进松散耦合,并且在事件驱动架构中特别有用。通过理解和实现这种模式,您可以编写更易于维护和扩展的代码。

版本声明 本文转载于:https://dev.to/hbolajraf/c-understanding-the-observer-pattern-1nm6如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    </main> <section> ,但无法使其正常工作,如您所见。任何洞察力都将不胜感激! display:grid; { position:sticky; top:1em; z-index:1 1 ; { { { pos...
    编程 发布于2025-02-07
  • 如何在Java中获取当前的UTC/GMT日期和时间?
    如何在Java中获取当前的UTC/GMT日期和时间?
    如何在Java中的UTC或GMT中获取当前日期和时间?即时类代表时间表上的特定时刻在UTC中具有纳秒精度。要将此瞬间转换为更易读的字符串表示形式,您可以使用toString()方法: instant.now()。 2016-09-13T23:30:52.123Z 注意:在Java 8之前,Jav...
    编程 发布于2025-02-07
  • 背景线程如何阻止在长期运行过程中winforms应用中的UI冻结?
    背景线程如何阻止在长期运行过程中winforms应用中的UI冻结?
    [2 防止winforms ui用背景线程冻结了长期运行的操作 Winforms应用程序中的长期运行,尤其是使用 此方法保持UI响应能力,从而显着改善了用户体验。 .NET提供了几种管理背景线程的机制,每个机制都提供不同的控制级别: 线程管理选项。 threadpool.queueuserwo...
    编程 发布于2025-02-07
  • Objectaid UML Explorer如何帮助您从Java代码生成UML图?
    Objectaid UML Explorer如何帮助您从Java代码生成UML图?
    从Java代码生成UML图:一种综合方法此工具在现有代码中无缝运行,消除了反向反向的需求工程。关键功能包括:实时图更新代码中的更改,确保连续对齐。自动图与源代码和库更新。与重构操作的无缝集成,确保图表与代码修改保持同步。跨工作区的全局图更新,自动从版本控制中查看必要的图表以进行进一步的对齐。 ,在...
    编程 发布于2025-02-07
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    如何为JavaScript对象变量创建动态键,尝试为JavaScript对象创建动态键,使用此Syntax jsObj['key' i] = 'example' 1;将不起作用。正确的方法采用方括号:他们维持一个长度属性,该属性反映了数字属性(索引)和一个数字属性的数量。标准对象没有模仿这...
    编程 发布于2025-02-07
  • 为什么我会得到\“ attributeError:module \'enum \'没有属性\'intflag \'\” python 3.6.1?
    为什么我会得到\“ attributeError:module \'enum \'没有属性\'intflag \'\” python 3.6.1?
    [ attributeError:module'enum'在python 3.6.1 一个可能的原因是Enum34软件包的存在,该软件包提供了与Python 3.4和更早版本的兼容性。但是,在Python 3.6及以后的情况下,不再需要Enum34的实现。要验证ENUM34是否正...
    编程 发布于2025-02-07
  • 如何使用Python的记录模块实现自定义处理?
    如何使用Python的记录模块实现自定义处理?
    使用Python的Loggging Module 确保正确处理和登录对于疑虑和维护的稳定性至关重要Python应用程序。尽管手动捕获和记录异常是一种可行的方法,但它可能乏味且容易出错。解决此问题,Python允许您覆盖默认的异常处理机制,并将其重定向为登录模块。这提供了一种方便而系统的方法来捕获和...
    编程 发布于2025-02-07
  • 操作员?= Java脚本
    操作员?= Java脚本
    JavaScript 的安全赋值运算符 ?=:简化异步操作中的错误处理 JavaScript 引入了一个新的运算符 ?=,称为安全赋值运算符。它旨在简化代码中的错误处理,使代码更易于阅读和维护,尤其是在处理 try-catch 错误捕获函数时。 ?= 运算符如何工作? 使用 ?= 运算符时,它会检...
    编程 发布于2025-02-07
  • 在保持其内容完整时,如何删除DIV元素?
    在保持其内容完整时,如何删除DIV元素?
    在保留其元素 display:cottents; display:cottents; cottents;在这种情况下是理想的选择。它导致元素的孩子出现为父母的直接子女,无视元素本身。当使用CSS网格或其他应该忽略包装元素的布局技术时,这是有价值的。 。容器{ 显示:Flex; } 。一 {...
    编程 发布于2025-02-07
  • 在JavaScript中声明变量时,为什么要始终使用\“ var \”?
    在JavaScript中声明变量时,为什么要始终使用\“ var \”?
    考虑以下示例:您可能希望此功能返回11;但是,由于“ varaible2 = 6”上的错别字,它返回了NAN。线。更糟糕的是,该错别字无意间创建一个全局变量,它具有拼写错误的名称“ varaible2。因此,强烈建议使用“ var”关键字,即使对于全局变量,也建议始终使用“ var”关键字来声明变...
    编程 发布于2025-02-06
  • 如何从大熊猫的大型文本数据集中有效删除标点符号?
    如何从大熊猫的大型文本数据集中有效删除标点符号?
    挑战: 这个问题在处理大型文本数据集时探索了str.replace的几种性能替代方案: 1。 REGEX.SUB:使用预编译的Regex模式从RE库中使用SUB函数。此方法对str.replace进行了重大的性能改进。 2。 str.translate:利用python的str.transla...
    编程 发布于2025-02-06
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。 To resolve this issue and ensure scripts execute on subsequent page visits, Firefox...
    编程 发布于2025-02-06
  • 我如何设计用于存储全球街道地址的最佳数据库?
    我如何设计用于存储全球街道地址的最佳数据库?
    确定全球街道地址的最佳数据库设计作为程序员,您会面临设计数据库的挑战来自世界各地。本文探讨了实现此目标的可能性,并提供了一种实用方法。 全局地址的常见数据库结构地址line(x4) 邮政编码 sub-building house/premise number 简化数据输入局部考虑[&&&&&&&...
    编程 发布于2025-02-06
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样?使用openssl?答案:可以使用mcrypt数据加密数据,可以使用openssl。关于如何使用openssl对McRypt进行加密的数据: openssl_decrypt...
    编程 发布于2025-02-06
  • 如何在Java列表中有效计算元素的发生?
    如何在Java列表中有效计算元素的发生?
    计数列表中的元素出现在列表 中,在java编程中,列举列表中列举元素出现的任务来自列表。为此,收集框架提供了全面的工具套件。在这种情况下,Batocurrences变量将保持值3,代表动物列表中的“ BAT”出现的数量。 &&& [此方法是简单的,可以得出准确的结果,使其成为计算列表中元素出现的理...
    编程 发布于2025-02-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3