C# 设计模式系列教程-观察者模式

C# 设计模式系列教程-观察者模式

什么是观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,主要用于在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都会得到通知并自动更新。观察者模式又被称为发布-订阅模式。

观察者模式实现分析

在观察者模式中,有两种角色,分别是被观察者和观察者。被观察者有一个列表存储它的所有观察者,并且支持动态增加和删除观察者。当被观察者的状态发生改变时,它会循环通知它的所有观察者执行特定的操作。

观察者模式的优势

  • 观察者模式降低了系统的耦合度。
  • 观察者模式增强了程序的灵活性和扩展性。
  • 观察者模式通过维护一对多的依赖关系,使得被观察者和观察者之间松散耦合。

观察者模式的应用场景

  • 当一个对象的改变需要同时改变其他对象时,而又不知道有多少对象需要改变时,使用观察者模式。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时,使用观察者模式。
  • 当一个对象必须通知其他对象,但是又不想和其他对象形成紧耦合关系时,使用观察者模式。

示例说明

示例1

下面我们来看一个简单的示例,模拟A公司发送消息到B公司,B公司接收消息的场景。

首先,我们定义一个抽象主题(Subject)接口,用于定义被观察者的行为。

public interface ISubject
{
    void RegisterObserver(IObserver observer);
    void RemoveObserver(IObserver observer);
    void NotifyObservers(string message);
}

然后,我们定义一个具体主题(ConcreteSubject)类,实现抽象主题接口,并在其中增加一个用于存储观察者的列表。

public class ConcreteSubject : ISubject
{
    private List<IObserver> observers;

    public ConcreteSubject()
    {
        this.observers = new List<IObserver>();
    }

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

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

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

接下来,我们定义一个抽象观察者(Observer)接口,用于定义观察者的行为。

public interface IObserver
{
    void Update(string message);
}

最后,我们定义一个具体观察者(ConcreteObserver)类,实现抽象观察者接口,并在其中实现观察者的行为。

public class ConcreteObserver : IObserver
{
    private string name;

    public ConcreteObserver(string name)
    {
        this.name = name;
    }

    public void Update(string message)
    {
        Console.WriteLine("{0} received the message: {1}", name, message);
    }
}

现在,我们可以编写下面的代码进行测试:

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

        // 创建观察者对象
        IObserver observer1 = new ConcreteObserver("Observer1");
        IObserver observer2 = new ConcreteObserver("Observer2");

        // 注册观察者对象
        subject.RegisterObserver(observer1);
        subject.RegisterObserver(observer2);

        // 发布消息
        subject.NotifyObservers("A公司发布了新产品");

        // 移除观察者对象
        subject.RemoveObserver(observer2);

        // 发布消息
        subject.NotifyObservers("A公司发布了优惠信息");

        Console.ReadLine();
    }
}

当我们执行以上代码后,将得到以下输出结果:

Observer1 received the message: A公司发布了新产品
Observer2 received the message: A公司发布了新产品
Observer1 received the message: A公司发布了优惠信息

示例2

在上面的示例中,我们使用了类似广播的方式通知所有的观察者。在某些情况下,我们可能需要对每个观察者执行不同的操作。这时可以将观察者作为消息的一部分进行传递,如下所示:

public class ConcreteSubject : ISubject
{
    // ...

    public void NotifyObservers(string message, IObserver observer)
    {
        observer.Update(message);
    }
}

当我们需要通知观察者时,只需要将观察者作为参数传递给被观察者的 NotifyObservers 方法即可。在实际开发中,我们可以在 IObserver 接口中新增一个 Notify 方法,然后让具体观察者类实现该方法即可。

总结

观察者模式是一种非常实用的设计模式,它可以帮助我们解决对象之间紧耦合关系的问题。在实际开发中,我们可以将观察者模式应用到很多场景中,如事件处理、页面自动更新等。使用观察者模式可以使得程序具有更好的可维护性、可扩展性和可复用性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 设计模式系列教程-观察者模式 - Python技术站

(0)
上一篇 2023年6月6日
下一篇 2023年6月6日

相关文章

  • C# 面向对象的基本原则

    C#面向对象的基本原则包括封装、继承和多态。以下是这些原则的详细说明。 封装 封装是一种将对象的状态数据和行为操作包装在一起的方式。这使得对象的内部实现细节对外部用户不可见。在C#中,我们使用访问修饰符来实现封装。 例如,下面是一个示例代码: public class Person { private string name; // 私有字段 public …

    C# 2023年5月15日
    00
  • 手把手教你如何基于C#制作一个网址检测工具

    手把手教你基于C#制作一个网址检测工具 简介 网址检测工具是一种用来检测网址是否可用的工具,可以帮助用户快速定位网站故障原因,提高用户的使用体验。该教程框架基于C#语言,本文将详细阐述如何基于C#制作一个网址检测工具。 准备工作 在开始之前,请先安装好 .NET环境,并下载安装 Visual Studio。 实现步骤 1. 创建项目 在 Visual Stu…

    C# 2023年6月6日
    00
  • 结合Visual C#开发环境讲解C#中事件的订阅和取消订阅

    本攻略将为你详细介绍如何在Visual C#开发环境中讲解C#中事件的订阅和取消订阅。 理解事件 在开始介绍事件的订阅和取消订阅之前,我们需要先理解事件的概念。在C#中,事件是用来描述当某种情况发生时应该采取的操作。事件由事件源和事件处理程序组成。 事件源是指导致事件发生的对象,其类型必须继承自System.Delegate类,可以将事件源看作一个发布者。事…

    C# 2023年6月1日
    00
  • Winform ComboBox如何独立绘制下拉选项的字体颜色

    要实现Winform ComboBox独立绘制下拉选项的字体颜色,可以采用以下步骤: 1. 继承ComboBox并重写OnDrawItem方法 我们需要自定义一个ComboBox控件,继承原有的ComboBox并重写OnDrawItem方法。在这个方法中,我们可以为每个下拉选项单独设置字体颜色。 public class CustomComboBox : C…

    C# 2023年6月6日
    00
  • ASP.NET:一段比较经典的多线程学习代码

    ASP.NET中的多线程编程可以极大地提高代码的执行效率,下面我将为大家讲解一段经典的多线程学习代码。这段代码涉及到了创建多个线程、线程之间的同步以及线程池等多个方面。 代码示例 下面是一个简单的多线程示例,该示例创建了两个线程,分别执行了两个不同的任务。 using System; using System.Threading; class Program…

    C# 2023年5月31日
    00
  • .NET使用DinkToPdf将HTML转成PDF的示例代码

    让我来给您详细讲解下“.NET使用DinkToPdf将HTML转成PDF的示例代码”的攻略吧。 什么是DinkToPdf DinkToPdf是一个开源的跨平台库,可以将HTML转换为PDF文档。它使用WKHtmlToPdf底层转换引擎,支持Windows,Linux和MacOS。 安装DinkToPdf 要使用DinkToPdf,您需要将它作为NuGet包添…

    C# 2023年6月3日
    00
  • 深入探究ASP.NET Core Startup初始化问题

    深入探究 ASP.NET Core Startup 初始化问题 在 ASP.NET Core 中,Startup 类是应用程序的入口点,它负责配置应用程序的服务和中间件。本攻略将深入探究 ASP.NET Core Startup 初始化问题,包括 Startup 类的构造函数、ConfigureServices 方法和 Configure 方法。 Start…

    C# 2023年5月17日
    00
  • 向一个数组中插入一个1~100的随机数

    关于向一个数组中插入一个1~100的随机数的完整攻略,具体步骤如下: 1. 声明一个数组 首先,需要在代码中声明一个数组,以便随后向其中插入随机数。可以使用如下语句: int[] arr = new int[n]; 其中,n代表数组的长度。这里使用了Java语言,如果是其他语言,语法可能略有不同,但是思路还是一致的。 2. 生成随机数 接着,需要生成一个1~…

    C# 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部