> Какие шаблоны проектирования часто используются (Go, Java)

Уровень: middle · Роль: backend · Категория: Технические вопросы

Компании: YADRO

Стек: Go, Java

> Пример ответа

Короткий ответ

Чаще всего в backend-разработке на Go и Java встречаются порождающие шаблоны: singleton, factory method, abstract factory, builder. Из структурных - repository, adapter, facade. Из поведенческих - strategy, observer, template method. В Go дополнительно популярны functional options и pipeline, а в Java - dependency injection через Spring-контекст, который по сути реализует service locator и factory. Важно не заучивать шаблоны, а понимать, какую проблему они решают.

Подробное объяснение

Шаблоны проектирования - это типовые решения повторяющихся задач. В backend-разработке они помогают управлять зависимостями, жизненным циклом объектов и отделять бизнес-логику от инфраструктуры.

Порождающие шаблоны решают вопрос создания объектов. В Java это особенно актуально из-за строгой типизации и многословности. В Go часто достаточно простых функций-конструкторов, поэтому часть шаблонов упрощается.

Структурные шаблоны определяют связи между классами и интерфейсами. Repository - стандарт для доступа к данным, он скрывает детали хранения. Adapter позволяет работать с legacy-кодом или сторонними библиотеками.

Поведенческие шаблоны описывают взаимодействие между объектами. Strategy удобен для алгоритмов, которые могут меняться в рантайме. Observer - основа event-driven архитектуры.

В Go из-за отсутствия наследования многие классические шаблоны трансформируются. Например, template method заменяется композицией функций, а visitor - type switch. В Java же классические GoF-шаблоны работают почти без изменений.

На практике

В реальных проектах на Java шаблоны часто скрыты за фреймворками. Spring использует proxy для реализации AOP, factory для бинов, template method в JdbcTemplate. Разработчику важно понимать, что происходит под капотом, чтобы правильно конфигурировать приложение.

В Go типичная практика - функциональные опции для конфигурации структур. Это замена builder-паттерна, но более идиоматичная. Также часто используют middleware-цепочки для HTTP-обработчиков - это вариация chain of responsibility.

Repository в обоих языках - стандарт для работы с БД. В Java это интерфейс с реализацией через JPA или MyBatis. В Go - интерфейс с реализацией через database/sql или sqlx.

Важный момент: не стоит применять шаблоны ради шаблонов. Если задача решается простым кодом - лучше без паттерна. Избыточная абстракция усложняет поддержку.

Пример кода

Go: functional options

GO
type Config struct {
Timeout time.Duration
Retries int
}
type Option func(*Config)
func WithTimeout(d time.Duration) Option {
return func(c *Config) {
c.Timeout = d
}
}
func WithRetries(n int) Option {
return func(c *Config) {
c.Retries = n
}
}
func NewClient(opts ...Option) *Client {
cfg := &Config{
Timeout: 5 * time.Second,
Retries: 3,
}
for _, opt := range opts {
opt(cfg)
}
return &Client{cfg: cfg}
}

Java: builder

JAVA
public class HttpClient {
private final int timeout;
private final int retries;
private final boolean followRedirects;
private HttpClient(Builder builder) {
this.timeout = builder.timeout;
this.retries = builder.retries;
this.followRedirects = builder.followRedirects;
}
public static class Builder {
private int timeout = 5000;
private int retries = 3;
private boolean followRedirects = true;
public Builder timeout(int timeout) {
this.timeout = timeout;
return this;
}
public Builder retries(int retries) {
this.retries = retries;
return this;
}
public HttpClient build() {
return new HttpClient(this);
}
}
}

Как отвечать на собеседовании

Начни с краткого перечисления основных групп шаблонов и их назначения. Затем приведи 2-3 примера из реальной практики: repository для работы с БД, strategy для обработки платежей, builder для конфигурации. Покажи понимание trade-off: когда шаблон уместен, а когда - избыточен.

Если спрашивают про конкретный шаблон, объясни проблему, которую он решает, приведи пример кода и расскажи, где он применяется в твоём стеке. Например, для singleton упомяни, что в Java это часто антипаттерн из-за проблем с тестированием, а в Go - просто переменная пакета.

Хорошо показать знание идиоматики языка: в Go - functional options вместо builder, в Java - dependency injection вместо service locator. Это демонстрирует не просто знание GoF, а понимание контекста.

Что проверяет интервьюер

Интервьюер оценивает не знание названий, а умение применять шаблоны для решения реальных задач. Важно показать, что ты понимаешь, какую проблему решает каждый шаблон и какие альтернативы существуют.

Проверяется способность объяснить trade-off: например, почему в Go не используют классический observer, а предпочитают каналы. Или почему в Java singleton часто заменяют на enum.

Также важно показать умение проектировать API: как сделать конструктор гибким, как скрыть детали реализации, как обеспечить тестируемость. Это базовые навыки, которые шаблоны помогают формализовать.

Типичные ошибки

  • Заучивание шаблонов без понимания проблемы - сразу видно, если попросить объяснить, зачем нужен шаблон.
  • Применение шаблонов везде подряд, даже там, где достаточно простого кода.
  • Путаница между похожими шаблонами: factory method vs abstract factory, strategy vs state.
  • Игнорирование идиоматики языка: попытка реализовать классический GoF-шаблон в Go так же, как в Java.
  • Неумение объяснить, когда шаблон не нужен, и какие есть альтернативы.
  • Отсутствие примеров из реальной практики - только теоретические определения.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью