← Назад к вопросам
Для чего нужен паттерн Фабрика Factory?
2.0 Middle🔥 201 комментариев
#SOLID и паттерны проектирования
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Паттерн Factory (Фабрика)
Назначение
Factory — это порождающий паттерн проектирования, который предоставляет интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов. Основная цель — инкапсулировать логику создания объектов и избавить клиента от необходимости знать конкретные классы.
Проблема, которую решает Factory
❌ Без паттерна:
// Клиентский код зависит от конкретных реализаций
if (databaseType.equals("mysql")) {
connection = new MySQLConnection();
} else if (databaseType.equals("postgresql")) {
connection = new PostgreSQLConnection();
} else if (databaseType.equals("oracle")) {
connection = new OracleConnection();
}
connection.connect();
Проблемы:
- Код зависит от конкретных классов
- Сложно добавлять новые типы
- Логика создания размазана по коду
- Нарушается принцип Open/Closed
Решение с Factory
✅ С паттерном:
// Интерфейс для всех типов соединений
public interface DatabaseConnection {
void connect();
void disconnect();
void executeQuery(String sql);
}
// Конкретные реализации
public class MySQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connecting to MySQL...");
}
@Override
public void disconnect() {
System.out.println("Disconnecting from MySQL...");
}
@Override
public void executeQuery(String sql) {
System.out.println("Executing MySQL query: " + sql);
}
}
public class PostgreSQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connecting to PostgreSQL...");
}
@Override
public void disconnect() {
System.out.println("Disconnecting from PostgreSQL...");
}
@Override
public void executeQuery(String sql) {
System.out.println("Executing PostgreSQL query: " + sql);
}
}
// Фабрика
public class DatabaseConnectionFactory {
public static DatabaseConnection createConnection(String databaseType) {
return switch (databaseType.toLowerCase()) {
case "mysql" -> new MySQLConnection();
case "postgresql" -> new PostgreSQLConnection();
case "oracle" -> new OracleConnection();
default -> throw new IllegalArgumentException(
"Unknown database type: " + databaseType
);
};
}
}
// Клиентский код
DatabaseConnection connection = DatabaseConnectionFactory.createConnection("mysql");
connection.connect();
connection.executeQuery("SELECT * FROM users");
connection.disconnect();
Типы Factory паттернов
1. Simple Factory (Простая фабрика)
Статический метод в утилитарном классе:
public class LoggerFactory {
public static Logger createLogger(LogLevel level) {
return switch (level) {
case DEBUG -> new DebugLogger();
case INFO -> new InfoLogger();
case ERROR -> new ErrorLogger();
};
}
}
2. Factory Method (Метод-фабрика)
Определяется в интерфейсе, реализуется в подклассах:
// Абстрактный класс с методом-фабрикой
public abstract class Document {
public abstract Application createApplication();
public void open() {
Application app = createApplication();
app.init();
}
}
// Конкретные реализации
public class PDFDocument extends Document {
@Override
public Application createApplication() {
return new PDFReader();
}
}
public class WordDocument extends Document {
@Override
public Application createApplication() {
return new WordProcessor();
}
}
// Использование
Document pdf = new PDFDocument();
pdf.open(); // Откроет PDF Reader
Document word = new WordDocument();
word.open(); // Откроет Word Processor
3. Abstract Factory (Абстрактная фабрика)
Создаёт семейства связанных объектов:
// Интерфейсы для компонентов UI
public interface Button {
void render();
}
public interface Checkbox {
void render();
}
// Фабрика для создания компонентов
public interface UIFactory {
Button createButton();
Checkbox createCheckbox();
}
// Реализации для Windows
public class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Rendering Windows button");
}
}
public class WindowsCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("Rendering Windows checkbox");
}
}
public class WindowsUIFactory implements UIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
// Реализации для macOS
public class MacButton implements Button {
@Override
public void render() {
System.out.println("Rendering macOS button");
}
}
public class MacCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("Rendering macOS checkbox");
}
}
public class MacUIFactory implements UIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
// Использование
UIFactory factory;
if (System.getProperty("os.name").contains("Windows")) {
factory = new WindowsUIFactory();
} else {
factory = new MacUIFactory();
}
Button button = factory.createButton();
Checkbox checkbox = factory.createCheckbox();
button.render();
checkbox.render();
Преимущества Factory
- Инкапсуляция — логика создания скрыта
- Слабая связанность — клиент зависит от интерфейса, не от реализаций
- Простота расширения — добавляем новый класс без изменения существующего кода (Open/Closed Principle)
- Централизованное управление — изменения в логике создания в одном месте
- Контроль — фабрика может кэшировать объекты, переиспользовать их
Примеры из Java API
// java.util.Calendar
Calendar calendar = Calendar.getInstance(); // Factory method
// java.nio.file.Files
Path path = Files.getPath("/etc/config");
// java.time
LocalDate date = LocalDate.now();
LocalDate date2 = LocalDate.of(2024, 3, 22);
// javax.xml.parsers
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Factory vs Constructor
| Аспект | Constructor | Factory |
|---|---|---|
| Сложность | Простой | Может быть сложным |
| Логика | Прямая | Может скрывать логику |
| Кэширование | Нет | Да |
| Полиморфизм | Нет | Да |
| Производительность | Быстро | Может быть медленнее |
Рекомендации
- Используй Factory когда нужна полиморфная создание объектов
- Используй Constructor когда логика создания простая
- Используй Abstract Factory для семейств объектов
- Комбинируй с Builder для сложных объектов с параметрами
Factory паттерн — фундаментальный паттерн для построения слабосвязанных и расширяемых систем.