Ответ
Abstract Factory (Абстрактная фабрика) — это порождающий паттерн проектирования, который предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не привязываясь к их конкретным классам.
Основная идея: Клиентский код работает только с абстрактными типами (Button, Checkbox, GUIFactory). Конкретная реализация фабрики (например, WindowsFactory) создает все продукты в едином, согласованном стиле.
Пример: Кроссплатформенный UI:
// 1. Абстрактные продукты
interface Button {
void render();
void onClick();
}
interface Checkbox {
void render();
void toggle();
}
// 2. Абстрактная фабрика
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 3. Конкретные продукты для Windows
class WindowsButton implements Button {
public void render() { System.out.println("Rendering a Windows-style button."); }
public void onClick() { System.out.println("Windows button clicked."); }
}
class WindowsCheckbox implements Checkbox { /* ... аналогично ... */ }
// 4. Конкретная фабрика для Windows
class WindowsFactory implements GUIFactory {
public Button createButton() { return new WindowsButton(); }
public Checkbox createCheckbox() { return new WindowsCheckbox(); }
}
// 5. Конкретные продукты и фабрика для MacOS (опущены для краткости)
// 6. Клиентский код
class Application {
private Button button;
private Checkbox checkbox;
public Application(GUIFactory factory) {
// Клиент не знает конкретных классов продуктов
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void renderUI() {
button.render();
checkbox.render();
}
}
// 7. Конфигурация (фабрика выбирается один раз, например, на основе ОС)
public class Main {
public static void main(String[] args) {
GUIFactory factory;
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("win")) {
factory = new WindowsFactory();
} else {
factory = new MacFactory();
}
Application app = new Application(factory);
app.renderUI();
}
}
Когда использовать Abstract Factory?
- Когда система должна быть независима от способа создания, композиции и представления своих объектов.
- Когда необходимо создавать семейства или группы связанных объектов, которые должны использоваться вместе.
- Когда нужно предоставить библиотеку продуктов, раскрывая только их интерфейсы, а не реализации.
Преимущества:
- Гарантирует сочетаемость создаваемых объектов.
- Изолирует клиентский код от конкретных классов.
- Упрощает замену целого семейства продуктов (например, переключение темы UI).
Недостатки:
- Сложность добавления нового вида продукта требует изменения интерфейса фабрики и всех её реализаций.
- Может привести к разрастанию числа классов (продукты * фабрики).
Отличие от Factory Method: Factory Method создает один продукт, а Abstract Factory создает семейство продуктов.