Какие основные категории паттернов проектирования и их примеры?

«Какие основные категории паттернов проектирования и их примеры?» — вопрос из категории Паттерны, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Паттерны проектирования делятся на три основные категории, каждая решает свой круг проблем.

1. Порождающие (Creational) Управляют процессом создания объектов, повышая гибкость и повторное использование кода.

  • Singleton: Гарантирует, что у класса существует только один экземпляр, и предоставляет к нему глобальную точку доступа.
  • Factory Method: Определяет интерфейс для создания объекта, но позволяет подклассам изменять тип создаваемых объектов.
  • Builder: Отделяет конструирование сложного объекта от его представления, позволяя использовать один и тот же процесс строительства для разных представлений.

2. Структурные (Structural) Объясняют, как собирать объекты и классы в более крупные структуры, сохраняя гибкость и эффективность.

  • Adapter: Позволяет объектам с несовместимыми интерфейсами работать вместе.
  • Decorator: Динамически добавляет объекту новые обязанности, являясь гибкой альтернативой наследованию.
  • Proxy: Предоставляет суррогат или заместитель другого объекта для контроля доступа к нему.

3. Поведенческие (Behavioral) Касаются эффективного взаимодействия и распределения ответственности между объектами.

  • Observer: Определяет зависимость «один-ко-многим» между объектами так, что при изменении состояния одного объекта все зависящие от него объекты уведомляются.
  • Strategy: Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми.
  • Command: Инкапсулирует запрос как объект, позволяя параметризовать клиентов с различными запросами, ставить их в очередь или логировать.

Пример Singleton на Java:

public class Singleton {
    // Статическая переменная для хранения единственного экземпляра
    private static Singleton instance;

    // Приватный конструктор предотвращает создание экземпляров извне
    private Singleton() {}

    // Публичный статический метод для глобального доступа к экземпляру
    public static Singleton getInstance() {
        if (instance == null) { // Ленивая инициализация
            instance = new Singleton();
        }
        return instance;
    }
}