什么是观察者模式
1 定义
观察者模式也称作发布/订阅模式,提供了一种作用于任何实现了订阅者接口的对象的机制, 可对其事件进行订阅和取消订阅。
2 例子
假如你有两种类型的对象: 顾客和商店。顾客希望商店某些商品有优惠信息的时候可以通知顾客。在这个例子中商店就是发布者,顾客就是订阅者。商店发布通知,维护订阅及取消订阅对象,如果顾客订阅了,则商店发布通知后顾客进行相应的处理。
3 实现
首先,声明订阅者接口。
//声明订阅者接口。
public interface IObserver
{
// 通知后处理
void Handle(ISubject subject);
}
然后,声明发布者接口并定义一些接口来在列表中添加和删除订阅对象。
public interface ISubject
{
// 订阅
void Subscribe(IObserver observer);
// 取消订阅
void Unsubscribe(IObserver observer);
// 发布
void Publish();
}
接着,创建具体发布者类。
//创建具体发布者类。
public class Subject : ISubject
{
private List<IObserver> _observers = new List<IObserver>();
public void Subscribe(IObserver observer)
{
this._observers.Add(observer);
}
public void Unsubscribe(IObserver observer)
{
this._observers.Remove(observer);
}
public void Publish()
{
Console.WriteLine("商店发布优惠通知!");
foreach (var observer in _observers)
{
observer.Handle(this);
}
}
}
接着,创建具体顾客类,顾客A和顾客B。
//具体订阅者类中实现通知后处理的方法。
public class CustomerA : IObserver
{
public void Handle(ISubject subject)
{
Console.WriteLine("顾客A收到优惠通知。");
}
}
public class CustomerB : IObserver
{
public void Handle(ISubject subject)
{
Console.WriteLine("顾客B收到优惠通知。");
}
}
最后,创建客户端类。
//客户端必须生成所需的全部订阅者, 并在相应的发布者处完成注册工作。
class Program
{
static void Main(string[] args)
{
var subject = new Subject();
var observerA = new CustomerA();
subject.Subscribe(observerA);
var observerB = new CustomerB();
subject.Subscribe(observerB);
subject.Publish();
Console.WriteLine();
subject.Unsubscribe(observerB);
subject.Publish();
Console.ReadKey();
}
}
让我们来看看输出结果:
商店发布优惠通知!
顾客A收到优惠通知。
顾客B收到优惠通知。
商店发布优惠通知!
顾客A收到优惠通知。
4 用.NET的事件模型来实现
.NET的事件模型是一种典型的观察者模型,代码相对来说更加简洁。
//创建具体发布者类。
public class Subject
{
public event Action Handles;
public void Publish()
{
Console.WriteLine("商店发布优惠通知!");
Handles?.Invoke();
}
}
//具体订阅者类中实现通知后处理的方法。
public class CustomerA
{
public void Handle()
{
Console.WriteLine("顾客A收到优惠通知。");
}
}
public class CustomerB
{
public void Handle()
{
Console.WriteLine("顾客B收到优惠通知。");
}
}
class Program
{
static void Main(string[] args)
{
var subject = new Subject();
var observerA = new CustomerA();
subject.Handles += observerA.Handle;
var observerB = new CustomerB();
subject.Handles += observerB.Handle;
subject.Publish();
Console.WriteLine();
subject.Handles -= observerB.Handle;
subject.Publish();
Console.ReadKey();
}
}
让我们来看看输出结果:
商店发布优惠通知!
顾客A收到优惠通知。
顾客B收到优惠通知。
商店发布优惠通知!
顾客A收到优惠通知。