是什么:
观察者模式是一种设计模式,它定义了对象之间的一种一对多的依赖关系,使得当一个对象状态发生改变时,它的所有依赖者都能够得到相应的通知并作出相应的反应。观察者模式也被称为发布-订阅模式。
为什么:
观察者模式可以实现对象之间的松耦合,从而使得对象更容易扩展和维护。同时,它也可以帮助我们实现一些实时通信的需求,如事件驱动的程序等。
怎么做:
在C#中,可以通过接口和委托来实现观察者模式。具体的做法是,定义一个接口,包含一个Update()方法,表示观察者需要在被通知时执行的操作;然后,在被观察者对象中定义一个List<IObserver>类型的观察者列表,每个观察者对象实现IObserver接口中的Update()方法,被观察者对象可以通过遍历观察者列表,并依次调用Update()方法来通知所有观察者对象。
何时用:
观察者模式常用于以下场景:
1.在多个对象之间需要有一种一对多的依赖关系,并且不希望关键对象和被依赖对象之间存在强耦合关系。
2.需要实现实时通信,如事件驱动的程序等。
3.需要通知多个对象,但又不知道这些对象的确切数量和类型时。
4.需要将各个对象解耦开来,使得它们的改动不会影响到其他对象。
如何实现:
在C#中,使用观察者模式的关键是要定义一个接口,包含一个Update()方法。这个方法表示观察者需要在被通知时执行的操作。
接口代码示例:
代码语言:javascript复制//观察者接口
public interface IObserver
{
void Update();
}
然后,在被观察者对象中定义一个List<IObserver>类型的观察者列表,并提供添加删除观察者的方法。被观察者对象的代码示例:
代码语言:javascript复制//被观察者抽象类
public abstract class Subject
{
private List<IObserver> _observers = new List<IObserver>();
//添加观察者
public void Attach(IObserver observer)
{
_observers.Add(observer);
}
//移除观察者
public void Detach(IObserver observer)
{
_observers.Remove(observer);
}
//通知观察者
public void Notify()
{
foreach (var observer in _observers)
{
observer.Update();
}
}
}
在被观察者抽象类中,定义了一个观察者列表,以及添加、移除观察者和通知观察者列表中的观察者的方法。
最后,具体的观察者对象需要实现IObserver接口中的Update()方法,以便在被通知时能够执行相应的操作。观察者对象的代码示例:
代码语言:javascript复制//具体观察者类1
public class ConcreteObserverA : IObserver
{
public void Update()
{
Console.WriteLine("ConcreteObserverA received the message.");
}
}
//具体观察者类2
public class ConcreteObserverB : IObserver
{
public void Update()
{
Console.WriteLine("ConcreteObserverB received the message.");
}
}
最后,我们可以在客户端中创建具体的被观察者对象和观察者对象,并将观察者对象添加到被观察者对象的观察者列表中,从而实现观察者模式的功能。
客户端代码示例:
代码语言:javascript复制class Client
{
static void Main(string[] args)
{
//创建被观察者对象
Subject subject = new ConcreteSubject();
//创建两个具体观察者对象并添加到被观察者对象的观察者列表中
IObserver observerA = new ConcreteObserverA();
IObserver observerB = new ConcreteObserverB();
subject.Attach(observerA);
subject.Attach(observerB);
//被观察者对象的状态改变,通知观察者对象
subject.ChangeState();
subject.Notify();
}
}
输出结果:
``` The subject's state has been changed. ConcreteObserverA received the message. ConcreteObserverB received the message. ```