C#设计模式之观察者模式实例讲解

C#设计模式之观察者模式实例讲解

概念介绍

观察者模式(Observer Pattern)是软件设计模式之一,它定义了对象之间的一种一对多的依赖关系,让多个观察者(Observers)对象同时监听某一个主题(Subject)对象。当这个主题对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。

观察者模式中有两个重要的部分:Subject 主题和 Observer 观察者。Subject 主题内部维护了一个订阅者列表,观察者 Observer 将自己注册到 Subject 主题对象的订阅者列表中,当 Subject 主题内部变化时,就可以通知所有注册的观察者对象更新。

实现步骤

具体的实现步骤如下:

  1. 定义 Subject 主题接口,包含注册、移除和通知订阅者等方法。
  2. 定义 Observer 观察者接口,包含更新方法。
  3. 实现具体的 Subject 主题类。
  4. 实现具体的 Observer 观察者类。
  5. 测试主题和观察者的交互。

示例说明

下面通过两个示例来演示观察者模式的使用方法。

示例一:银行利率变化

假设有一家银行,它的利率会时常更新,为了及时通知客户,银行创建了一个 Subject 主题类 Bank,客户作为观察者 Observer 订阅了该主题。

public interface IBank
{
    void Attach(ICustomer customer);   // 添加观察者
    void Detach(ICustomer customer);   // 移除观察者
    void Notify();                     // 通知观察者
    decimal InterestRate { get; set; } // 利率属性
}

public class Bank : IBank
{
    private List<ICustomer> _customers = new List<ICustomer>();
    private decimal _interestRate;

    public decimal InterestRate
    {
        get { return _interestRate; }
        set
        {
            if (_interestRate != value)
            {
                _interestRate = value;
                Notify(); // 通知观察者
            }
        }
    }

    public void Attach(ICustomer customer)
    {
        _customers.Add(customer);
    }

    public void Detach(ICustomer customer)
    {
        _customers.Remove(customer);
    }

    public void Notify()
    {
        foreach (var customer in _customers)
        {
            customer.Update(this); // 更新观察者状态
        }
    }
}

public interface ICustomer
{
    void Update(IBank bank); // 更新观察者状态
}

public class Customer : ICustomer
{
    private readonly string _name;

    public Customer(string name)
    {
        _name = name;
    }

    public void Update(IBank bank)
    {
        Console.WriteLine($"{_name} - 今日利率为 {bank.InterestRate}");
    }
}

在客户端代码中,银行利率发生变化时,会自动通知所有的客户:

static void Main(string[] args)
{
    IBank bank = new Bank();

    var customer1 = new Customer("小明");
    var customer2 = new Customer("小红");

    bank.Attach(customer1);
    bank.Attach(customer2);

    bank.InterestRate = 0.03m; // 利率变化导致通知观察者更新

    bank.Detach(customer2); // 移除一个观察者

    bank.InterestRate = 0.04m; // 利率变化导致通知观察者更新

    Console.ReadLine();
}

输出结果:

小明 - 今日利率为 0.03
小红 - 今日利率为 0.03
小明 - 今日利率为 0.04

示例二:微信公众号文章发布

假设有一家微信公众号,管理员发布了一篇文章,为了及时通知所有订阅者,微信公众号创建了一个 Subject 主题类 WeChat,订阅者作为观察者 Observer 订阅了该主题。

public interface IWeChat
{
    void Attach(ISubscriber subscriber); // 添加观察者
    void Detach(ISubscriber subscriber); // 移除观察者
    void Notify(string article); // 通知观察者
}

public class WeChat : IWeChat
{
    private readonly List<ISubscriber> _subscribers = new List<ISubscriber>();

    public void Attach(ISubscriber subscriber)
    {
        _subscribers.Add(subscriber);
    }

    public void Detach(ISubscriber subscriber)
    {
        _subscribers.Remove(subscriber);
    }

    public void Notify(string article)
    {
        foreach (var subscriber in _subscribers)
        {
            subscriber.Receive(article); // 更新观察者状态
        }
    }
}

public interface ISubscriber
{
    void Receive(string article); // 更新观察者状态
}

public class Subscriber : ISubscriber
{
    private readonly string _name;

    public Subscriber(string name)
    {
        _name = name;
    }

    public void Receive(string article)
    {
        Console.WriteLine($"{_name} - 收到新文章:{article}");
    }
}

在客户端代码中,当管理员发布一篇文章时,会自动通知所有订阅者:

static void Main(string[] args)
{
    IWeChat wechat = new WeChat();

    var subscriber1 = new Subscriber("小明");
    var subscriber2 = new Subscriber("小红");

    wechat.Attach(subscriber1);
    wechat.Attach(subscriber2);

    wechat.Notify("观察者模式实例讲解"); // 发布新文章导致通知观察者更新

    wechat.Detach(subscriber2); // 移除一个观察者

    wechat.Notify("微信公众号设计模式"); // 发布新文章导致通知观察者更新

    Console.ReadLine();
}

输出结果:

小明 - 收到新文章:观察者模式实例讲解
小红 - 收到新文章:观察者模式实例讲解
小明 - 收到新文章:微信公众号设计模式

总结

观察者模式是一种非常重要的设计模式,提供了一种松耦合的方式,使得被观察者和观察者之间变得灵活可扩展。在实际开发中,我们要善于运用设计模式来优化代码结构,提高代码重用性、可维护性和可测试性。

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

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • 基于C#生成随机数示例

    生成随机数是很常见的一种需求,无论是在游戏、金融还是科学领域,都需要使用到随机数。C#作为一门强大的编程语言,自然也提供了非常方便的方法来生成随机数。 下面是生成随机数的完整攻略。 步骤一 – 声明随机数生成器 首先,我们需要创建 Random 类型的对象,来帮助我们生成随机数。 在 C# 中,我们可以使用以下代码生成随机数生成器: Random rando…

    C# 2023年6月1日
    00
  • PowerShell中的加法运算详解

    那我就为您详细讲解一下“PowerShell中的加法运算详解”。 一、加法运算简介 在PowerShell中,加法运算使用“+”符号表示。加法运算可以完成两种类型的操作: 两个数字相加 使用加法运算,可以将两个数相加,然后得出它们的和。 # 例1:将数字1和数字2相加 PS C:\> $a = 1 PS C:\> $b = 2 PS C:\&gt…

    C# 2023年6月8日
    00
  • C#实现闹钟AlarmClock实例代码

    下面是详细讲解“C#实现闹钟AlarmClock实例代码”的完整攻略: 1. 确定需求 我们要实现一个简单的闹钟程序,具有设置闹钟时间、开启闹钟、关闭闹钟等功能。 2. 创建C#控制台应用程序 打开Visual Studio,选择“新建项目”,选择“Visual C#”类型,“控制台应用程序”模板,输入项目名称,点击“创建”按钮。这样就创建了一个空白的控制台…

    C# 2023年6月6日
    00
  • C# 批量生成随机密码必须包含数字和字母并用加密算法加密

    生成随机密码是一个经常需要的需求,而加密这些密码更是必须的。在这里,我们可以使用C#来编写代码,实现批量生成随机密码,并用加密算法加密的功能。 以下是实现流程: 步骤1:确定要使用的加密算法 在 .NET Framework 中,我们可以使用多种加密算法,例如:DES、Triple DES、AES、RSA等。在此过程中,我们将使用AES加密算法来加密这些密码…

    C# 2023年6月8日
    00
  • c#:CTS类型系统

    C#中的CTS类型系统(Common Type System)是一种规范,用于确保不同类型的语言在互相交互时能够进行正确的类型转换和操作。下面将分别从三个方面对CTS类型系统进行讲解。 CTS数据类型 C#的数据类型分为值类型和引用类型两类。值类型用于存储简单数据类型如数字、字符等,而引用类型则用于所有需要动态分配内存的复杂数据类型,如字符串、数组、类等。下…

    C# 2023年6月8日
    00
  • C#实现的文件压缩和解压缩类

    关于C#实现的文件压缩和解压缩类的完整攻略,我可以提供如下的讲解: 一、为什么需要文件压缩和解压缩 当需要传输或者存储大量文件时,文件压缩是非常必要的。压缩文件可以减小文件的体积,从而减少传输和存储的时间和空间。压缩文件可以降低互联网网络和存储的压力,也可以提高数据传输的速度和带宽。 二、使用C#来实现文件压缩和解压缩 C#提供了很多方式来实现文件的压缩和解…

    C# 2023年6月1日
    00
  • C#中字符串编码处理

    C#中字符串的编码处理需要涉及到多个类和方法。下面将从以下三个方面进行详细说明: 字符集 C#中使用Unicode字符集表示字符串,同时也支持使用ASCII和UTF-8字符集。Unicode字符集定义了每个字符与二进制编码之间的映射关系。ASCII字符集是Unicode字符集的子集,只包含128个常用字符。UTF-8字符集是一种变长编码,可以用1-4个字节表…

    C# 2023年6月7日
    00
  • 遍历文件系统目录树的深入理解

    遍历文件系统目录树的深入理解 遍历文件系统目录树是我们在开发的过程中经常会用到的操作之一,可以用来查找文件、文件夹,或者对一个文件夹下面的所有文件进行批量处理。本文将介绍如何使用 Python 的 os 模块来遍历文件系统目录树。 使用 os.walk() 方法 Python 提供了 os.walk() 方法,它可以用来遍历目录树。这个方法的返回值是一个迭代…

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