Как ответить
Паттерны проектирования — это типовые решения часто встречающихся проблем в ООП. Они не код, а шаблон, который ускоряет разработку, делает код понятнее для других и уменьшает риск ошибок. Обычно их делят на три группы по цели.
Порождающие — управляют созданием объектов. Самый известный — Singleton: гарантирует, что у класса один экземпляр. Годится для логгера или пула подключений, но злоупотреблять не стоит — создаёт скрытые зависимости. Фабричный метод (Factory Method) — определяет интерфейс для создания объекта, а подклассы выбирают конкретный класс. Пример: рендеринг разных форматов — PDF, HTML — через единый метод createRenderer(). Строитель (Builder) нужен, когда объект собирается из множества опциональных частей: скажем, SQL-запрос собирается цепочкой методов Select(...).From(...).Where(...).
Структурные — описывают, как собрать классы и объекты в крупные структуры. Адаптер (Adapter) позволяет двум несовместимым интерфейсам работать вместе: например, старую CRM подключаем к новой системе через обертку, которая конвертирует вызовы. Декоратор (Decorator) динамически добавляет обязанности объекту, не меняя его класс — типичный пример: обёртка чтения из файла с буферизацией или сжатием. Компоновщик (Composite) трактует индивидуальные объекты и их группы единообразно: дерево компонентов UI, где каждый элемент — простой виджет или панель с дочерними элементами.
Поведенческие — распределяют обязанности между объектами и описывают, как они общаются. Стратегия (Strategy) инкапсулирует семейство алгоритмов и делает их взаимозаменяемыми. В языках с функциями высшего порядка (JS, Python) он почти эволюционировал в передачу лямбды. Наблюдатель (Observer) — один объект оповещает множество подписчиков об изменении своего состояния — основа событийной архитектуры. Команда (Command) превращает запрос в объект — полезно для отмены/повтора операций или очереди задач.
Главное — паттерны не панацея. Я встречал код, где Singleton везде, и отладка превращалась в ад. Для junior-позиции достаточно знать три группы и уметь на пальцах объяснить 2-3 паттерна из каждой. На собеседовании я бы упомянул принцип: «композиция важнее наследования» — многие структурные и поведенческие паттерны как раз его реализуют.
Пример кода для Singleton в Java с ленивой инициализацией:
public class Database {
private static volatile Database instance;
private Database() {}
public static Database getInstance() {
if (instance == null) {
synchronized (Database.class) {
if (instance == null) {
instance = new Database();
}
}
}
return instance;
}
}