← Назад к вопросам

Как реализован паттерн Abstract Factory?

2.3 Middle🔥 191 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Паттерн 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

  1. Изоляция создания объектов - клиент не знает о конкретных классах
  2. Согласованность - гарантирует использование совместимых объектов
  3. Легкое добавление новых семейств - просто добавьте новую фабрику
  4. Соответствие Single Responsibility Principle - логика создания отделена
  5. Соответствие Open/Closed Principle - открыто для расширения, закрыто для модификации

Недостатки

  1. Усложнение кода - больше классов и интерфейсов
  2. Может быть избыточен - для простых случаев
  3. Сложность добавления новых продуктов - требует изменения интерфейса

Когда использовать

  • Система должна быть независима от способа создания объектов
  • Система работает с несколькими семействами связанных продуктов
  • Нужна возможность переключаться между реализациями
  • Приложение поддерживает множество платформ или конфигураций

Сравнение с Factory Method

АспектAbstract FactoryFactory Method
ЦельСоздание семейств объектовСоздание одного типа объекта
ИнтерфейсыНесколько методов созданияОдин метод создания
СложностьВышеНиже
ПрименениеПлатформенные/конфигурационныеПростое порождение

Вывод

Abstract Factory - это мощный паттерн для управления созданием семейств связанных объектов. Он обеспечивает гибкость, масштабируемость и соответствие SOLID принципам. Используйте его, когда нужна возможность переключаться между различными реализациями без изменения клиентского кода.