陈巧倩

设计模式-观察者模式

· 275 words · 2 minutes to read
Categories: CSharp
Tags: Design Pattern

Observer观察者模式属于行为型设计模式,观察者设计模式定义了对象之间的一对多依赖关系,以便当一个对象更改状态时,它的所有依赖项都会得到通知并自动更新。

Design Pattern:Observer 🔗

基本介绍 🔗

构成 🔗

  • Subject:抽象主题类,持有所有观察者对象的引用保存在一个列表中,并提供注册和删除观察者对象的操作,并且保证消息时序性。
  • ConcreteSubject:具体主题类,负责跟踪Subject的状态并通知观察者其中的任何变化。
  • Observer:抽象观察者类,定义更新观察者状态的接口。
  • ConcreteObserver:具体观察者类,实现观察者更新接口,使其状态与主体保持一致。

优点 🔗

  • 表示层和数据逻辑层的分离,并实现了稳定的更新消息传递机制。
  • 允许添加更多观察者而无需更改主题的代码,即它支持开放/关闭原则。
  • 被观察者和观察者之间建立了一个抽象的耦合,被观察者并不知道任何一个具体的观察者,只是保存着抽象观察者的列表,每个具体观察者都符合一个抽象观察者的接口。

缺点 🔗

  • 被观察者被很多观察者订阅,向所有的观察者都通知到会花费很多时间。
  • 对于观察者来讲,消息的来源无法确定。

实例 🔗

C#中观察者模式的实例,终于到月初了,我们开始给员工发工资,然后银行会给每个员工发送短信。

/// <summary>
/// 抽象观察者类
/// </summary>
public abstract class Account
{
    /// <summary>
    /// 账户名
    /// </summary>
    protected string _name;
    /// <summary>
    /// 账户金额
    /// </summary>
    protected int _total;

    /// <summary>
    /// 账户是否变更
    /// </summary>
    public bool bChange;
    public Account(string name,int total)
    {
        _name = name;
        _total = total;
    }

    /// <summary>
    /// 发工资
    /// </summary>
    /// <param name="salary"></param>
    public void SetGalaryMoney(int salary)
    {
        _total += salary;
    }

    /// <summary>
    /// 账户资产变更
    /// </summary>
    public abstract void Update();
}

/// <summary>
/// 具体观察者类
/// </summary>
public class EmployeeAccout : Account
{
    public EmployeeAccout(string name, int total) : base(name, total)
    {

    }

    /// <summary>
    /// 账户资产变更
    /// </summary>
    public override void Update()
    {
        Console.WriteLine($"{_name} : total {_total}");
    }
}

/// <summary>
/// 被观察者基类-抽象主题类
/// </summary>
public abstract class BankMessageSystem
{
    /// <summary>
    /// 观察者李彪
    /// </summary>
    protected List<Account> _observers = new List<Account>();
    /// <summary>
    /// 注册账号
    /// </summary>
    /// <param name="account"></param>
    public abstract void RegAccount(Account account);
    /// <summary>
    /// 移除账号
    /// </summary>
    /// <param name="account"></param>
    public abstract void UnRegAccount(Account account);
    /// <summary>
    /// 发送通知
    /// </summary>
    public void Notify()
    {
        for (int i = 0; i < _observers.Count; i++)
        {
            if (_observers[i].bChange)
            {
                _observers[i].Update();
                _observers[i].bChange = false;
            }
        }
    }
}

/// <summary>
/// 具体观察者类
/// </summary>
public class HomeLandBank : BankMessageSystem
{
    public override void RegAccount(Account account)
    {
        _observers.Add(account);
    }

    public override void UnRegAccount(Account account)
    {
        _observers.Remove(account);
    }
}

实际运行:

Account dongwenyi = new EmployeeAccout("dongwenyi", 100);
Account sunchangpeng = new EmployeeAccout("sunchangpeng", 100000);

HomeLandBank bank = new HomeLandBank();
bank.RegAccount(dongwenyi);
bank.RegAccount(sunchangpeng);

dongwenyi.SetGalaryMoney(100);
sunchangpeng.SetGalaryMoney(10000);

bank.Notify();

结论 🔗

搬砖愉快!