一、啥是观察者模式和WCF
1. 观察者模式
咱先说说观察者模式。这就好比你订阅了一份报纸,报社就是被观察的对象,而你就是观察者。当报社有新报纸出来的时候,就会主动给你送过来。在编程里,就是一个对象(被观察对象)状态发生变化时,会通知所有依赖它的对象(观察者)。这样可以让对象之间的耦合度降低,方便扩展。
2. WCF 是啥
WCF 呢,全称是 Windows Communication Foundation,是微软搞出来的一个框架,用来构建分布式应用程序。它能让不同的应用程序之间进行通信,就像不同城市的人打电话交流一样。WCF 支持多种协议,比如 HTTP、TCP 啥的,很灵活。
二、为啥要在 WCF 里用观察者模式实现服务事件实时通知
1. 应用场景
想象一下有这么个场景,你在开发一个股票交易系统。当某只股票的价格发生变化时,你得马上通知所有关注这只股票的用户。这时候,WCF 就可以作为服务器,和客户端进行通信,而观察者模式就能很好地实现股票价格变化的实时通知。
2. 优点和缺点
优点
- 松耦合:观察者和被观察者之间的联系不那么紧密,修改一方不会对另一方产生太大影响。就像你换了一家报社订阅报纸,对报社来说只是少了一个订阅者,对其他订阅者没啥影响。
- 可扩展性强:要是想增加新的观察者,很容易,直接加就行。比如股票交易系统里,有新用户关注某只股票,直接把他加到观察者列表里。
- 实时通知:能及时把服务的状态变化通知给观察者。
缺点
- 内存泄漏风险:如果观察者没有正确注销,会一直占用内存。就像你不看报纸了,但没有取消订阅,报社还一直给你送,占地方。
- 性能问题:如果有大量的观察者,通知的时间会变长,影响性能。
三、具体咋实现
1. 定义服务契约
咱用 C# 来实现,这是一种常见的.NET 语言。下面是定义服务契约的代码:
// C# 技术栈
// 定义服务契约接口
using System.ServiceModel;
// 服务契约接口,用于定义服务的操作
[ServiceContract]
public interface IStockService
{
// 订阅股票价格变化的方法
[OperationContract]
void Subscribe(IStockObserver observer);
// 取消订阅股票价格变化的方法
[OperationContract]
void Unsubscribe(IStockObserver observer);
// 模拟更新股票价格的方法
[OperationContract]
void UpdateStockPrice(string stockName, decimal price);
}
// 定义观察者接口
[ServiceContract]
public interface IStockObserver
{
// 当股票价格变化时,调用此方法通知观察者
[OperationContract(IsOneWay = true)]
void StockPriceChanged(string stockName, decimal price);
}
在这段代码里,IStockService 是服务契约接口,定义了订阅、取消订阅和更新股票价格的方法。IStockObserver 是观察者接口,有一个 StockPriceChanged 方法,当股票价格变化时会调用这个方法通知观察者。
2. 实现服务
// C# 技术栈
using System;
using System.Collections.Generic;
// 服务实现类
public class StockService : IStockService
{
// 存储观察者的列表
private readonly List<IStockObserver> _observers = new List<IStockObserver>();
// 实现订阅方法
public void Subscribe(IStockObserver observer)
{
if (!_observers.Contains(observer))
{
_observers.Add(observer);
}
}
// 实现取消订阅方法
public void Unsubscribe(IStockObserver observer)
{
if (_observers.Contains(observer))
{
_observers.Remove(observer);
}
}
// 实现更新股票价格方法
public void UpdateStockPrice(string stockName, decimal price)
{
// 遍历所有观察者,通知他们股票价格变化
foreach (var observer in _observers)
{
try
{
observer.StockPriceChanged(stockName, price);
}
catch (Exception ex)
{
// 处理异常,比如客户端连接断开
Console.WriteLine($"Error notifying observer: {ex.Message}");
}
}
}
}
在 StockService 类里,用一个列表 _observers 来存储所有的观察者。Subscribe 方法用来添加观察者,Unsubscribe 方法用来移除观察者,UpdateStockPrice 方法会遍历所有观察者,调用他们的 StockPriceChanged 方法通知股票价格变化。
3. 客户端代码
// C# 技术栈
using System;
using System.ServiceModel;
// 客户端观察者实现类
public class StockObserver : IStockObserver
{
// 实现股票价格变化通知方法
public void StockPriceChanged(string stockName, decimal price)
{
Console.WriteLine($"Stock {stockName} price changed to {price}");
}
}
class Program
{
static void Main()
{
// 创建服务代理
var factory = new ChannelFactory<IStockService>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8080/StockService"));
var service = factory.CreateChannel();
// 创建观察者实例
var observer = new StockObserver();
// 订阅股票价格变化
service.Subscribe(observer);
// 模拟更新股票价格
service.UpdateStockPrice("ABC", 100.50m);
// 取消订阅
service.Unsubscribe(observer);
// 关闭服务代理
((ICommunicationObject)service).Close();
Console.ReadLine();
}
}
客户端代码里,StockObserver 类实现了 IStockObserver 接口,当收到股票价格变化通知时,会在控制台输出信息。在 Main 方法里,创建了服务代理,订阅了股票价格变化,模拟更新了股票价格,最后取消订阅。
四、注意事项
1. 异常处理
在通知观察者时,可能会出现异常,比如客户端连接断开。所以要在服务端做好异常处理,避免程序崩溃。就像上面代码里,在 UpdateStockPrice 方法里用 try-catch 块来捕获异常。
2. 线程安全
如果有多个线程同时访问观察者列表,可能会出现线程安全问题。可以使用锁机制来保证线程安全,比如在 Subscribe 和 Unsubscribe 方法里加锁。
3. 资源管理
观察者在不需要接收通知时,要及时取消订阅,避免内存泄漏。就像你不看报纸了,要及时取消订阅。
五、总结
在 WCF 里应用观察者模式实现服务事件的实时通知,能让系统更灵活、可扩展,还能实现实时更新。但也有一些缺点,比如内存泄漏和性能问题,需要我们在开发过程中注意。通过上面的示例,我们可以看到具体的实现步骤,掌握了这些,就能在实际项目中运用这个技术了。
评论