📜  观察者 - C# (1)

📅  最后修改于: 2023-12-03 15:27:54.700000             🧑  作者: Mango

观察者模式 - C#

观察者模式是一种设计模式,它允许对象之间建立一对多的依赖关系,当对象的状态改变时,所有依赖它的对象都可通过被通知而自动更新。

为什么使用观察者模式?

在软件开发中,经常会遇到一些对象之间需要实时通讯的场景,当某个对象的状态发生改变时,需要立即更新其它相关对象的状态。这时,我们可以使用观察者模式来实现,它使得对象之间建立一种松耦合关系,可以方便地进行扩展和维护。观察者模式的 PUB-SUB 模型也被广泛应用于数据通信中。

如何实现观察者模式?

在 C# 中,可以使用 System 命名空间下的 Observable 类和 Observer 接口来实现观察者模式。下面是一个简单的示例。

创建 Subject 类

首先,我们需要一个主题类,用于维护观察者列表,以及通知观察者状态改变的方法。

public class Subject : IObservable<string>
{
    private List<IObserver<string>> observers = new List<IObserver<string>>();
    private string state = string.Empty;

    public void UpdateState(string newState)
    {
        state = newState;
        NotifyObservers();
    }

    public IDisposable Subscribe(IObserver<string> observer)
    {
        if (!observers.Contains(observer))
            observers.Add(observer);

        return new Unsubscriber(observers, observer);
    }

    private void NotifyObservers()
    {
        foreach (var observer in observers)
            observer.OnNext(state);
    }
}

上述代码定义了一个 Subject 类,实现了 IObservable<string> 接口,这个接口定义了观察者模式中的被观察者(主题)需要实现的方法。其中包括:

  • Subscribe: 在观察者列表中添加一个观察者,并返回一个 IDisposable 对象,持有这个对象可以取消观察者的注册。
  • Unsubscribe: 取消一个观察者的注册。
  • OnNext: 通知观察者主题状态发生了改变。

Subject 类中,我们维护了一个观察者列表,当主题状态改变时,通过 NotifyObservers 方法通知所有观察者状态发生了改变。

创建 Observer 类

接下来,我们需要一个观察者类,用于响应主题状态的改变。

public class Observer : IObserver<string>
{
    private IDisposable unsubscriber;
    private string observerName;

    public Observer(string name)
    {
        this.observerName = name;
    }

    public virtual void Subscribe(IObservable<string> provider)
    {
        if (provider != null)
            unsubscriber = provider.Subscribe(this);
    }

    public void OnCompleted()
    {
        Console.WriteLine("数据流传输完成。");
    }

    public void OnError(Exception e)
    {
        Console.WriteLine("传输数据时出错了!");
    }

    public void OnNext(string value)
    {
        Console.WriteLine($"{observerName} 收到了新的数据:{value}");
    }

    public virtual void Unsubscribe()
    {
        unsubscriber.Dispose();
    }
}

上述代码定义了一个观察者类 Observer,实现了 IObserver<string> 接口,这个接口定义了观察者模式中的观察者需要实现的方法。其中包括:

  • Subscribe: 注册自己到主题的观察者列表。
  • Unsubscribe: 取消注销自己的注册。
  • OnNext: 响应主题的状态变化。

Observer 类中,我们通过实现这些方法来响应主题的状态变化,并打印出它们的名称和新状态的值。同时,我们也定义了一个 Unsubscribe 方法来自行取消注册。

测试代码

最后,我们创建一个测试类,在其中创建一个 Subject 对象和两个 Observer 对象。

public class TestObserver
{
    public void Run()
    {
        var subject = new Subject();

        var observer1 = new Observer("Observer 1");
        observer1.Subscribe(subject);

        var observer2 = new Observer("Observer 2");
        observer2.Subscribe(subject);

        subject.UpdateState("New State 1");
        observer1.Unsubscribe();

        subject.UpdateState("New State 2");
    }
}

上述代码定义了一个 TestObserver 类,其中创建了一个主题对象 subject,以及两个观察者对象 observer1observer2。我们通过调用 Subscribe 方法将这两个观察者注册到主题中,然后通过调用 UpdateState 方法改变主题的状态。最后,我们调用 Unsubscribe 方法取消了 observer1 的注册。

运行结果

最终,我们可以看到以下输出:

Observer 1 收到了新的数据:New State 1
Observer 2 收到了新的数据:New State 1
Observer 2 收到了新的数据:New State 2
数据流传输完成。
总结

观察者模式是一种常见的设计模式,在 C# 中可以通过 Observable 类和 Observer 接口来实现。它可以帮助我们构建松耦合的对象系统,有效地实现关注分离和可扩展性。