> Какие группы паттернов проектирования существуют (Go)
Уровень: senior · Роль: backend · Категория: Технические вопросы
Компании: Aston
Стек: Go
> Пример ответа
Короткий ответ
Выделяют три классические группы паттернов проектирования: порождающие (creational), структурные (structural) и поведенческие (behavioral). Порождающие управляют процессом создания объектов, структурные определяют композицию классов и объектов, поведенческие описывают взаимодействие и распределение ответственности между объектами. В Go часто используют упрощённые варианты из-за отсутствия наследования и наличия интерфейсов и композиции.
Подробное объяснение
Классификация из GoF (Gang of Four) остаётся базовой:
-
Порождающие - скрывают механизм инстанцирования, делают систему независимой от способа создания объектов. Примеры: singleton, factory method, abstract factory, builder, prototype. В Go вместо классического наследования применяются интерфейсы и функции-конструкторы.
-
Структурные - упрощают проектирование за счёт определения отношений между сущностями. Примеры: adapter, facade, decorator, composite, proxy. В Go часто реализуются через композицию структур и интерфейсов, а не через наследование.
-
Поведенческие - решают задачи эффективного взаимодействия между объектами, распределяют алгоритмы и ответственность. Примеры: strategy, observer, chain of responsibility, command, state. В Go активно используются функции как значения первого класса, что упрощает реализацию многих поведенческих паттернов.
Дополнительно выделяют паттерны уровня архитектуры (например, repository, unit of work, CQRS), но они не входят в классическую триаду GoF. Для Go важно понимать, что некоторые классические паттерны либо не нужны (например, singleton часто заменяют пакетом с глобальной переменной), либо реализуются идиоматично через интерфейсы и замыкания.
На практике
Для senior-позиции важно не просто перечислить группы, а показать понимание, когда паттерн оправдан, а когда - избыточен. В Go-проектах часто встречаются:
- Порождающие: функции-конструкторы с опциями (functional options), пул объектов (sync.Pool) вместо singleton.
- Структурные: middleware как декоратор для HTTP-обработчиков, адаптеры для работы с внешними API.
- Поведенческие: стратегия для обработки платежей, observer через каналы и горутины, chain of responsibility в виде цепочки middleware.
Кандидат должен уметь объяснить trade-off: паттерн решает конкретную проблему, но добавляет абстракцию. В Go часто проще написать простую функцию или структуру, чем разворачивать полную реализацию паттерна из учебника.
Пример кода
Порождающий паттерн на Go - функциональные опции вместо builder:
GOtype Server struct {host stringport inttls bool}type Option func(*Server)func WithHost(host string) Option {return func(s *Server) { s.host = host }}func WithPort(port int) Option {return func(s *Server) { s.port = port }}func WithTLS(tls bool) Option {return func(s *Server) { s.tls = tls }}func NewServer(opts ...Option) *Server {s := &Server{host: "localhost", port: 8080}for _, opt := range opts {opt(s)}return s}
Поведенческий паттерн - стратегия через интерфейс:
GOtype PaymentStrategy interface {Pay(amount float64) error}type CardPayment struct{}func (CardPayment) Pay(amount float64) error {// обработка картойreturn nil}type CryptoPayment struct{}func (CryptoPayment) Pay(amount float64) error {// обработка криптойreturn nil}type Checkout struct {strategy PaymentStrategy}func (c *Checkout) SetStrategy(s PaymentStrategy) {c.strategy = s}func (c *Checkout) Process(amount float64) error {return c.strategy.Pay(amount)}
Как отвечать на собеседовании
Начните с чёткого перечисления трёх групп и их назначения. Затем приведите по одному примеру из каждой группы, желательно на Go. Покажите, что понимаете, как особенности языка влияют на реализацию: отсутствие наследования, наличие интерфейсов, горутин и каналов. Упомяните, что в Go некоторые паттерны упрощаются или заменяются идиоматичными конструкциями. Если спросят про конкретный паттерн, объясните проблему, которую он решает, и приведите минимальный пример. Не пытайтесь перечислить все паттерны - лучше глубоко разобрать 2-3.
Что проверяет интервьюер
Интервьюер оценивает:
- базовое знание классификации GoF;
- умение применять паттерны в контексте Go, а не механически переносить примеры из Java или C++;
- понимание trade-off: когда паттерн полезен, а когда создаёт лишнюю сложность;
- способность объяснить, как идиомы Go (интерфейсы, композиция, функции как значения) влияют на реализацию;
- умение привести релевантный пример из реальной практики.
Типичные ошибки
- Перечисление паттернов без объяснения, какую проблему они решают.
- Слепое копирование реализации из других языков без учёта особенностей Go.
- Утверждение, что в Go паттерны не нужны - это крайность, паттерны полезны, но их применение должно быть осознанным.
- Путаница между группами, например, отнесение adapter к поведенческим.
- Излишнее усложнение ответа: для senior достаточно краткого, но точного объяснения с примерами.
> Похожие задачи по backend
Почему Map не наследуется от коллекций
Для чего нужны магические методы в PHP
В чем отличие массивов в PHP от массивов в других языках
Что происходит при несовпадении типов и как происходит проверка типов в PHP
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью