Какие паттерны входят в джентльменский набор
Что проверяют
Знаете ли вы, как паттерны выглядят именно в Go, где нет классов и наследования, зато есть интерфейсы, композиция и горутины. Пересказ каталога GoF с Java-примерами тут скорее минус. Следом часто просят написать functional options или worker pool.
Как отвечать
Для каждого паттерна называйте идиому Go:
- конструктор
NewX: простая фабрика, возвращает конкретную структуру. Правило «принимай интерфейсы, возвращай структуры»; - functional options:
NewServer(addr, WithTimeout(5*time.Second)). Заменяет Builder и конструкторы с десятком параметров; - Singleton:
sync.Onceили появившиеся в Go 1.21sync.OnceValueиsync.OnceFunc. Но зависимость лучше явно передать в конструктор; - Decorator: middleware вида
func(http.Handler) http.Handlerдля логирования, авторизации, recover; - Adapter:
http.HandlerFuncпревращает функцию вhttp.Handler; - Strategy: маленький интерфейс или параметр-функция, как
lessвsort.Slice; - worker pool: фиксированное число горутин читает задачи из канала;
- pipeline и fan-out/fan-in: этапы, связанные каналами, с отменой через
context.Context; - ограничение параллелизма: буферизованный канал как семафор или
errgroupсSetLimit.
Добавьте Go-специфику: интерфейсы объявляют на стороне потребителя и держат маленькими, как io.Reader с одним методом. Observer часто делают на каналах, и тут стоит сразу сказать, что будет с медленным подписчиком: издатель заблокируется или события начнут отбрасываться.
Где спотыкаются
Переносят Java-стиль: абстрактные фабрики, интерфейс на каждую структуру заранее, иерархии через встраивание. Код получается многословным и чужим для Go.
Хвалят Singleton на глобальной переменной. Глобальное состояние мешает тестам, ревьюер спросит, почему не внедрение через конструктор.
Рисуют pipeline без отмены. Если потребитель перестал читать, горутины этапов навсегда повисают на отправке в канал, это утечка.