В каких сценариях применяется паттерн Abstract Factory?

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

Ответ

Abstract Factory используется для создания семейств связанных или зависимых объектов без указания их конкретных классов. Основные сценарии применения:

  • Кросс-платформенные интерфейсы: Создание UI-компонентов (кнопок, полей ввода) для разных операционных систем (Windows, macOS, Linux).
  • Абстракция от конкретных баз данных: Фабрики для создания репозиториев или подключений к различным СУБД (PostgreSQL, MySQL, Oracle).
  • Игровые движки: Генерация тематических семейств объектов (например, персонажей, оружия и построек в стилях фэнтези или научной фантастики).
  • Конфигурируемые комплектующие: Создание совместимых компонентов для разных конфигураций продукта.

Пример на Java:

// Абстрактные продукты
interface Button { void render(); }
interface Checkbox { void paint(); }

// Конкретные продукты для Windows
class WinButton implements Button {
    public void render() { System.out.println("Render Windows button"); }
}
class WinCheckbox implements Checkbox {
    public void paint() { System.out.println("Paint Windows checkbox"); }
}

// Абстрактная фабрика
interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// Конкретная фабрика для Windows
class WinFactory implements GUIFactory {
    public Button createButton() { return new WinButton(); }
    public Checkbox createCheckbox() { return new WinCheckbox(); }
}

// Клиентский код работает только с абстракциями
public class Application {
    private Button button;
    private Checkbox checkbox;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }
    public void paint() {
        button.render();
        checkbox.paint();
    }
}

Почему это полезно: Клиентский код (Application) не зависит от конкретных классов создаваемых объектов, что упрощает поддержку и добавление новых семейств продуктов.