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

yizhihongxing

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# StringBuilder操作性能优化的方法

    提高C# StringBuilder操作性能优化的方法 前言 StringBuilder是C#语言中常用的字符串操作类之一,用于对字符串进行动态操作,比如追加、替换、插入等。在进行大量字符串操作时,使用StringBuilder可以提高性能,而不必像使用字符串拼接时那样频繁创建和销毁字符串对象。但是,如果使用不得当,StringBuilder也可能出现性能问…

    C# 2023年6月8日
    00
  • C#几种获取网页源文件代码的实例

    C#几种获取网页源文件代码的实例 1. 使用 WebClient 获取 首先,引入命名空间 System.Net: using System.Net; 然后只需要使用 WebClient 类即可获取网页源文件: string url = "https://www.example.com"; using (WebClient client …

    C# 2023年6月1日
    00
  • .net实现oracle数据库中获取新插入数据的id的方法

    下面我为您提供在.NET中实现Oracle数据库中获取新插入数据的id方法的完整攻略: 1. 使用SEQUENCE序列 使用SEQUENCE序列是一种常见的获取新插入数据ID的方式。步骤如下: 首先在Oracle数据库中创建一个SEQUENCE序列:CREATE SEQUENCE seq_id START WITH 1 INCREMENT BY 1 MINV…

    C# 2023年6月3日
    00
  • unity 如何获取Text组件里text内容的长度

    获取Text组件中包含的文本内容长度是通过Unity中提供的string.Length属性实现的。下面是获取Text组件中文本内容长度的完整攻略: 步骤一:获取Text组件对象 使用GameObject.GetComponent()函数获取文本对象的Text组件。例如: Text textComponent = GetComponent<Text&gt…

    C# 2023年6月3日
    00
  • C#微信接口之推送模板消息功能示例

    C#微信接口之推送模板消息功能示例是一篇介绍在C#中实现微信公众号推送模板消息功能的文章,下面我将进行详细讲解。 一、文章概述 本文主要介绍在C#中如何实现微信公众号推送模板消息功能。首先介绍了微信公众号的基本概念和开发环境的搭建。然后详细讲解了推送模板消息的实现原理和流程,并给出了两个示例说明。 二、微信公众号开发环境 微信公众号是基于微信平台提供的功能,…

    C# 2023年5月31日
    00
  • C#多线程学习(一) 多线程的相关概念

    C#多线程学习(一) 多线程的相关概念 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。 什么是线程? 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等), 但代码区是共享的,即不同的线程可以执行同样的函数。 什么是多线程? 多线程是指程序…

    C# 2023年4月17日
    00
  • VsCode使用EmmyLua插件调试Unity工程Lua代码的详细步骤

    详细讲解“VsCode使用EmmyLua插件调试Unity工程Lua代码的详细步骤”的完整攻略如下: 1. 准备工作 首先,我们需要确保我们的环境中已经安装了以下软件:1. Visual Studio Code(简称VsCode)2. Unity3. Lua环境4. EmmyLua插件 2. 配置Unity 在Unity中,我们需要做以下配置:1. 打开Pl…

    C# 2023年5月15日
    00
  • Asp.NET调用百度翻译的方法

    当我们需要在Asp.NET程序中使用百度翻译服务时,可以通过百度翻译提供的API接口来实现。下面是在Asp.NET中调用百度翻译的方法攻略: 1.申请百度翻译API接口的app id和密钥 在使用百度翻译API之前,需要在百度开发者平台申请app id和密钥。具体步骤如下: 1)进入百度开发者中心(https://console.bce.baidu.com/…

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