发布-订阅模式 (Publish-Subscribe Pattern)
发布-订阅模式是一种消息通信模式,它允许多个订阅者监听特定类型的消息,当消息发布时,所有订阅该类型的订阅者都会收到消息。这种模式通常用于异步通信和事件驱动的系统。
关键角色:
- Publisher(发布者) 发送消息的对象。
- Subscriber(订阅者) 接收消息的对象。
- Broker(中间人/事件总线) 管理发布者和订阅者之间的通信,可以是显式的也可以是隐式的。
这段代码展示了如何创建一个简单的 EventAggregator
类,它允许发布和订阅泛型事件。在实际应用中可能需要更复杂的逻辑来处理线程安全、内存泄漏预防以及更精细的事件管理需求。不过,对于理解基本概念,这个示例应该足够了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| public class EventAggregator { private Dictionary<string, List<Action<string>>> _subscribers = new(); public void Subscribe(string eventName, Action<string> action) { if (!_subscribers.ContainsKey(eventName)) { _subscribers[eventName] = new List<Action<string>>(); } _subscribers[eventName].Add(action); } public void Unsubscribe(string eventName, Action<string> action) { if (_subscribers.ContainsKey(eventName)) { _subscribers[eventName].Remove(action); } } public void Publish(string eventName, string data) { if (_subscribers.ContainsKey(eventName)) { foreach (var action in _subscribers[eventName]) { action(data); } } } }
public class Publisher { private EventAggregator _eventAggregator; public Publisher(EventAggregator eventAggregator) { _eventAggregator = eventAggregator; } public void PublishEvent(string message) { _eventAggregator.Publish("WeatherUpdate", message); } }
public class Subscriber { private EventAggregator _eventAggregator; public Subscriber(EventAggregator eventAggregator) { _eventAggregator = eventAggregator; _eventAggregator.Subscribe("WeatherUpdate", OnWeatherUpdate); } private void OnWeatherUpdate(string message) { Console.WriteLine($"Subscriber received: {message}"); } }
|
实际上使用C#时通常不需要再实现一个 EventAggregator
类,因为C#原生的 event
就已经实现了类似功能。
使用event
这种方式更加贴近C#的事件处理机制,同时也简化了管理订阅者逻辑的需求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public delegate void WeatherUpdateEventHandler(string message);
public class Publisher { public event WeatherUpdateEventHandler WeatherUpdated; public void PublishEvent(string message) { WeatherUpdated?.Invoke(message); } }
public class Subscriber { public void Subscribe(Publisher publisher) { publisher.WeatherUpdated += OnWeatherUpdate; } public void Unsubscribe(Publisher publisher) { publisher.WeatherUpdated -= OnWeatherUpdate; } private void OnWeatherUpdate(string message) { Console.WriteLine($"Subscriber received: {message}"); } } class Program { static void Main(string[] args) { Publisher publisher = new Publisher(); Subscriber subscriber = new Subscriber(); subscriber.Subscribe(publisher); publisher.PublishEvent("It's raining today!"); Console.ReadKey(); } }
|
在C#中,事件(event)机制本身就是用来实现发布-订阅模式的一个强大工具,它允许对象之间进行松耦合的通信。当一个对象(发布者)的状态改变时,它可以触发一个事件,而其他对这个事件感兴趣的对象(订阅者)可以注册处理程序来响应这个事件。这种模式在很多场景下非常有用,尤其是当需要解耦组件并促进模块化设计时。
尽管如此,在某些复杂的项目或架构中,特别是那些采用如MVVM(Model-View-ViewModel)等设计模式的应用里,可能会发现使用一个 EventAggregator
类更加方便和灵活。EventAggregator
通常作为一个服务存在,允许任何数量的组件发布事件而不必直接引用彼此,同时也能让其他组件订阅这些事件,即使它们之间没有直接的依赖关系。这在大型应用中特别有用,因为它有助于管理大量的事件类型,并且可以更容易地控制事件的生命周期和范围。
类似于在观察者模式中提到过的,同样的,如果想进一步”简化代码”,可以使用 EventHandler
和 EventArgs
类,这两个类是 C# 中内置的用于事件处理的基类。不过到这一步,观察者模式和发布-订阅模式之间的区别就显得比较模糊了。这两种模式的核心都是关于对象之间的解耦通信,选择哪一种主要取决于设计偏好和项目的具体需求。