什么是观察者模式
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收到优惠通知。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)