Какие паттерны проектирования применить для процессора с выбором стратегии обработки по типу события
Что проверяют
Умеете ли вы решить задачу идиоматично для Go: интерфейсом из одного метода и таблицей обработчиков, а не переносом Java-иерархий. Следом обычно просят добавить новый тип события и спрашивают, сколько мест в коде придётся поменять.
Как отвечать
Базовая схема собирается из трёх приёмов:
- Стратегия: интерфейс
Handlerс методомHandle(ctx context.Context, e Event) error. Для простых случаев удобен адаптерHandlerFuncпо образцуhttp.HandlerFunc; - реестр вместо switch:
map[EventType]Handler, заполненный при старте. Процессор достаёт обработчик по типу, а для неизвестного типа возвращает ошибку или отдаёт событие обработчику по умолчанию. Новый тип добавляется одной регистрацией, процессор не меняется; - Декоратор (middleware): функции вида
func(Handler) Handlerдля логирования, метрик, ретраев и таймаутов. Их навешивают на любой обработчик, не трогая его код.
Если на одно событие реагируют несколько независимых обработчиков, это уже Наблюдатель (pub/sub): в реестре лежит срез обработчиков, и ошибка одного не должна останавливать остальных. Команда уместна, когда событие нужно сохранить и выполнить позже, например положить в очередь с повторами.
Для небольшого закрытого набора типов обычный switch e := ev.(type) читается лучше реестра, и это нормально сказать вслух. Про конкурентность: реестр, который после инициализации только читают, безопасен без блокировок; если обработчики регистрируются на лету, нужен sync.RWMutex.
Где спотыкаются
Делают SetStrategy на общем процессоре и меняют стратегию перед каждым событием. При обработке в нескольких горутинах это гонка: событие уйдёт не в тот обработчик, и go test -race это сразу покажет.
Пишут в обычную map из разных горутин во время работы. Рантайм завершает программу с fatal error: concurrent map read and map write, и это не паника: recover её не перехватит.
Путают Стратегию и Наблюдатель. Стратегия выбирает один алгоритм под событие, Наблюдатель рассылает событие всем подписчикам, и гарантии по ошибкам и порядку у них разные.