Канал событий () — фундаментальный шаблон проектирования, используется для создания канала связи и коммуникации через него посредством событий. Этот канал обеспечивает возможность разным издателям публиковать события и подписчикам, подписываясь на них, получать уведомления.
Является расширением шаблона «издатель — подписчик», добавляя к нему функции, которые присущи распределённой среде. Так канал является централизованным и подписчик может получать опубликованные события от более, чем одного объекта, даже если он зарегистрирован только на одном канале.
В общем случае шаблон Канал событий описывает интерфейс для объектов-представителей для подписки на канал событий и для объектов-представителей для публикации событий в рамках канала. Использование неких представителей позволяет взаимодействовать настоящим издателям и подписчикам вне рамок самого канала, но посредством него.
Концептуальное описание канала событий показано ниже:
Шаблон Канал событий использует сильно типизированные события; это означает, что подписчик может ожидать поступления определенных типов данных события, если регистрируется для определенного события. Он также позволяет подписчику отправлять события, а не только получать события, посланные ему.
Применение
public interface IEventChannel { void Publish(string topic, string data); void Subscribe(string topic, ISubscriber subscriber); }
public interface IPublisher { void Publish(string data); }
public interface ISubscriber { void Notify(string data); }
public class EventChannel: IEventChannel { private Dictionary<string, List<ISubscriber>> _topics = new Dictionary<string, List<ISubscriber>>();
public void Publish(string topic, string data)
if(!_topics.ContainsKey(topic)) return; foreach(var subscriber in _topics[topic]) subscriber.Notify(data);
public void Subscribe(string topic, ISubscriber subscriber)
if(_topics.ContainsKey(topic)) _topics[topic].Add(subscriber); else _topics.Add(topic, new List<ISubscriber>() { subscriber });
public class Publisher: IPublisher { private string _topic; private IEventChannel _channel; public Publisher(string topic, IEventChannel channel)
_topic = topic; _channel = channel;
public void Publish(string data)
_channel.Publish(_topic, data);
public class Subscriber: ISubscriber { private string _name; public Subscriber(string name)
_name = name;
public void Notify(string data)
Console.Write($"Subscriber '{_name}' notify: '{data}'")
static class Program { public void Main(string[] args)
var channel = new EventChannel(); var publisherA = new Publisher("#topic.a", channel); var publisherB = new Publisher("#topic.b", channel); var subscriberA = new Subscriber("Reader 1"); var subscriberB = new Subscriber("Reader 2");
channel.Subscribe("#topic.a", subscriberA); channel.Subscribe("#topic.a", subscriberB); channel.Subscribe("#topic.b", subscriberB);
// Console write: Subscriber 'Reader 1' notify: 'Text1' // Console write: Subscriber 'Reader 2' notify: 'Text1' publisherA.Publish("Text1");
// Console write: Subscriber 'Reader 2' notify: 'Text2' publisherB.Publish("Text2");
Достоинства Шаблон Канал событий позволяет легко и быстро создать каналы для публикации и обработки событий (или сообщений), при этом исключив прямого взаимодействия между издателем и подписчиком, что снижает связность объектов и упрощает тестирование.
Недостатки При реализации шаблона Канал событий увеличивается сложность приложения.
См. также Издатель-подписчик (Publish/Subscribe) Наблюдатель (Observer) Событийно-ориентированное программирование
Примечания
Литература Programming in the large with Design Patterns, Eddie Burris Java design patterns 201: Beyond the Gang of Four. 2002. Learning Javascript Design Patters, Addy Osmani
Ссылки Шаблон Event Channel Observer vs Pub-Sub Publish-Subscribe Channel Differences Between the Observer and Publish/Subscribe Pattern JavaScript Design Patterns
Категория:Шаблоны проектирования