Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Паттерн Abstract Factory
Abstract Factory - это порождающий паттерн проектирования, который позволяет создавать семейства связанных объектов без привязки к конкретным классам их реализации.
Основная идея
Паттерн решает задачу создания объектов, когда нужно работать с семействами связанных продуктов. Например, кроссплатформенный интерфейс, который должен работать на разных операционных системах.
┌─────────────────────────────────────┐
│ Abstract Factory │
│ (интерфейс для создания семеств) │
└─────────────────────────────────────┘
↑ ↑
│ │
┌──────────────┐ ┌──────────────┐
│WindowsFactory│ │ MacOSFactory │
│(создаёт │ │(создаёт │
│Windows │ │macOS │
│компоненты) │ │компоненты) │
└──────────────┘ └──────────────┘
Структура паттерна
1. Абстрактный интерфейс фабрики
// Интерфейс Abstract Factory
public interface UIFactory {
Button createButton();
CheckBox createCheckBox();
TextField createTextField();
}
2. Абстрактные интерфейсы продуктов
// Интерфейсы для семейства продуктов
public interface Button {
void click();
void render();
}
public interface CheckBox {
void check();
void render();
}
public interface TextField {
void setText(String text);
void render();
}
3. Конкретные реализации (семейство Windows)
public class WindowsButton implements Button {
@Override
public void click() {
System.out.println("Windows button clicked");
}
@Override
public void render() {
System.out.println("Rendering Windows button with system appearance");
}
}
public class WindowsCheckBox implements CheckBox {
@Override
public void check() {
System.out.println("Windows checkbox checked");
}
@Override
public void render() {
System.out.println("Rendering Windows checkbox");
}
}
public class WindowsTextField implements TextField {
@Override
public void setText(String text) {
System.out.println("Windows textfield set: " + text);
}
@Override
public void render() {
System.out.println("Rendering Windows textfield");
}
}
4. Конкретные реализации (семейство macOS)
public class MacOSButton implements Button {
@Override
public void click() {
System.out.println("macOS button clicked");
}
@Override
public void render() {
System.out.println("Rendering macOS button with Aqua look and feel");
}
}
public class MacOSCheckBox implements CheckBox {
@Override
public void check() {
System.out.println("macOS checkbox checked");
}
@Override
public void render() {
System.out.println("Rendering macOS checkbox");
}
}
public class MacOSTextField implements TextField {
@Override
public void setText(String text) {
System.out.println("macOS textfield set: " + text);
}
@Override
public void render() {
System.out.println("Rendering macOS textfield");
}
}
5. Конкретные фабрики
// Конкретная фабрика для Windows
public class WindowsUIFactory implements UIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public CheckBox createCheckBox() {
return new WindowsCheckBox();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
}
// Конкретная фабрика для macOS
public class MacOSUIFactory implements UIFactory {
@Override
public Button createButton() {
return new MacOSButton();
}
@Override
public CheckBox createCheckBox() {
return new MacOSCheckBox();
}
@Override
public TextField createTextField() {
return new MacOSTextField();
}
}
6. Клиентский код
public class Application {
private Button button;
private CheckBox checkbox;
private TextField textfield;
public Application(UIFactory factory) {
// Создаём компоненты через фабрику
// Не знаем конкретную реализацию!
button = factory.createButton();
checkbox = factory.createCheckBox();
textfield = factory.createTextField();
}
public void render() {
button.render();
checkbox.render();
textfield.render();
}
}
// Использование
public class Main {
public static void main(String[] args) {
String os = System.getProperty("os.name").toLowerCase();
UIFactory factory;
if (os.contains("win")) {
factory = new WindowsUIFactory();
} else {
factory = new MacOSUIFactory();
}
Application app = new Application(factory);
app.render();
}
}
Реальный пример: Система уведомлений
// Интерфейсы продуктов
public interface Notification {
void send(String message);
}
public interface NotificationFactory {
Notification createEmailNotification();
Notification createSMSNotification();
Notification createPushNotification();
}
// Windows реализация
public class WindowsEmailNotification implements Notification {
@Override
public void send(String message) {
System.out.println("Sending Windows email: " + message);
}
}
public class WindowsNotificationFactory implements NotificationFactory {
@Override
public Notification createEmailNotification() {
return new WindowsEmailNotification();
}
@Override
public Notification createSMSNotification() {
return new WindowsSMSNotification();
}
@Override
public Notification createPushNotification() {
return new WindowsPushNotification();
}
}
// Использование в приложении
public class NotificationService {
private NotificationFactory factory;
public NotificationService(NotificationFactory factory) {
this.factory = factory;
}
public void notifyUser(String message) {
Notification email = factory.createEmailNotification();
email.send(message);
}
}
Abstract Factory в Spring Framework
// Spring использует Abstract Factory для создания бинов
@Configuration
public class DataSourceFactory {
@Bean
@Profile("production")
public DataSource productionDataSource() {
return new ProductionDataSource();
}
@Bean
@Profile("development")
public DataSource developmentDataSource() {
return new H2DataSource();
}
@Bean
@Profile("test")
public DataSource testDataSource() {
return new TestDataSource();
}
}
// Инъекция в зависимости от профиля
@Service
public class UserService {
@Autowired
private DataSource dataSource; // Выбирается автоматически
public List<User> getAllUsers() {
// Работает с любым DataSource
}
}
Преимущества Abstract Factory
- Изоляция создания объектов - клиент не знает о конкретных классах
- Согласованность - гарантирует использование совместимых объектов
- Легкое добавление новых семейств - просто добавьте новую фабрику
- Соответствие Single Responsibility Principle - логика создания отделена
- Соответствие Open/Closed Principle - открыто для расширения, закрыто для модификации
Недостатки
- Усложнение кода - больше классов и интерфейсов
- Может быть избыточен - для простых случаев
- Сложность добавления новых продуктов - требует изменения интерфейса
Когда использовать
- Система должна быть независима от способа создания объектов
- Система работает с несколькими семействами связанных продуктов
- Нужна возможность переключаться между реализациями
- Приложение поддерживает множество платформ или конфигураций
Сравнение с Factory Method
| Аспект | Abstract Factory | Factory Method |
|---|---|---|
| Цель | Создание семейств объектов | Создание одного типа объекта |
| Интерфейсы | Несколько методов создания | Один метод создания |
| Сложность | Выше | Ниже |
| Применение | Платформенные/конфигурационные | Простое порождение |
Вывод
Abstract Factory - это мощный паттерн для управления созданием семейств связанных объектов. Он обеспечивает гибкость, масштабируемость и соответствие SOLID принципам. Используйте его, когда нужна возможность переключаться между различными реализациями без изменения клиентского кода.