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#.NET 写txt文件小例子

    下面是详细的攻略: 1. 准备工作 在开始编写代码之前,需要准备好以下工具和环境: 电脑上已安装 .NET Framework。 某个文本编辑器或 IDE,比如 Visual Studio。 一些基本的 C# 编程知识。 2. 创建 C# 项目 创建一个新的 C# 项目: 打开 Visual Studio,选择 “新建项目”。 在弹出的 “新建项目” 窗口中…

    C# 2023年5月31日
    00
  • 老生常谈.NET中的 COM 组件

    COM(Component Object Model) 是一种基于二进制的软件组件技术,它可用于跨语言和跨机器边界提供组件交互,是一种早期的应用程序组件化技术。在 .NET 开发中,我们可以使用 COM 组件来实现和调用外部非 .NET 的框架或组件。 COM 组件简介 COM 组件是一种通过二进制接口进行交互的组件,其二进制接口包括方法、属性、事件等。CO…

    C# 2023年6月3日
    00
  • C#省份城市下拉框联动简单实现方法

    当用户需要在网页上选择省份和城市时,通常会使用联动下拉框,即选择省份后再根据省份的选择来显示相应的城市。C#作为一种常见的后端语言,其实现联动下拉框非常简单。下面我们来详细讲解”C#省份城市下拉框联动简单实现方法”。 其实现步骤如下: 1.前端页面设计 首先我们需要一个前端页面,用于展示下拉框。在这个页面中,我们需要提供两个下拉框,一个选择省份,一个选择城市…

    C# 2023年5月31日
    00
  • 深入多线程之:深入分析Interlocked

    深入多线程之:深入分析Interlocked 介绍 多线程编程中,线程间的数据共享是必不可少的。但是,由于线程间数据的竞争,可能会存在数据异常的情况。而Interlocked类提供了一些原子性的操作,避免了竞争,从而保证线程间数据的准确性。 Interlocked 类及其方法 Interlocked 类的定义为:用于在多个线程之间提供原子操作的方法。 Int…

    C# 2023年6月7日
    00
  • C#利用后缀表达式解析计算字符串公式

    关于C#利用后缀表达式解析计算字符串公式,我们可以按照以下步骤来实现: 第一步:将中缀表达式转换为后缀表达式 将中缀表达式转换为后缀表达式有许多种算法,这里我们介绍一种简单的算法: 新建一个栈和一个列表; 从左到右遍历中缀表达式的每一个元素,每次处理一个元素; 如果该元素是数字,将其加入列表; 如果该元素是运算符,将其压入栈中,先判断栈顶元素的运算符与其优先…

    C# 2023年6月7日
    00
  • C#多线程系列之读写锁

    C# 多线程系列之读写锁 什么是读写锁? 读写锁允许同时有多个线程来读取共享资源,但一次只允许一个线程来写入共享资源。这可能会带来一些好处,比如更快的数据访问速度。 读写锁的基本思想是: 如果它是一个读访问,它可以并发进行。 如果它是一个写入访问,则它需要独占式地进行。 读写锁的实现方式 ReaderWriterLock 在 .NET Framework 3…

    C# 2023年6月1日
    00
  • C#中三种Timer计时器的详细用法

    当我们需要在C#中执行一些定时任务时,我们可以使用Timer计时器。在C#中,有三种不同的Timer计时器,分别是System.Timers.Timer、System.Threading.Timer和System.Windows.Forms.Timer。下面,我们将分别介绍它们的详细用法。 System.Timers.Timer System.Timers.…

    C# 2023年6月1日
    00
  • ASP.NET Core使用EF创建模型(必需和可选属性、最大长度、并发标记、阴影属性)

    在 ASP.NET Core 中,可以使用 Entity Framework (EF) 来创建模型。EF 是一个 ORM 框架,可以将数据库中的表映射到 C# 类中。以下是 ASP.NET Core 中使用 EF 创建模型的完整攻略: 步骤一:安装 EF 在使用 EF 前,需要在 ASP.NET Core 项目中安装 EF。可以使用 NuGet 包管理器或者…

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