Шаблон фабричного метода
Определяйте фабричный метод в базовом классе и позволяйте подклассам решать, какой продукт создавать.
«Шаблон фабричного метода» — бесплатный урок Java Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Назначение паттерна «Фабричный метод»
Фабричный метод определяет интерфейс для создания объекта, но позволяет подклассам решать, экземпляр какого класса создавать. Он отделяет логику создания от клиентского кода.
Проблема без фабричного метода
Без фабрики клиентский код пестрит вызовами new ConcreteClass(). Добавление нового варианта означает изменение каждого места вызова — нарушение принципа открытости/закрытости.
// Client knows too much:
Shape shape;
if (type.equals("circle")) shape = new Circle(r);
else if (type.equals("rect")) shape = new Rectangle(w, h);
// Every new shape requires editing this code.Абстрактный класс-создатель
Определите абстрактный класс-создатель с фабричным методом createProduct(). Подклассы переопределяют его, чтобы возвращать конкретные типы продуктов.
public abstract class Dialog {
public void render() {
Button btn = createButton(); // factory method
btn.onClick();
}
protected abstract Button createButton();
}Конкретные создатели
Каждый подкласс переопределяет фабричный метод, чтобы возвращать подходящий продукт, не изменяя окружающий алгоритм в базовом классе.
public class WindowsDialog extends Dialog {
@Override
protected Button createButton() { return new WindowsButton(); }
}
public class WebDialog extends Dialog {
@Override
protected Button createButton() { return new HtmlButton(); }
}Интерфейс продукта
Все конкретные продукты реализуют общий интерфейс, поэтому создатель может работать с ними обобщённо.
public interface Button {
void onClick();
void render();
}
public class WindowsButton implements Button {
public void onClick() { System.out.println("Windows click"); }
public void render() { System.out.println("Render Windows button"); }
}Статические фабричные методы и паттерн «Фабричный метод»
Статический фабричный метод, например LocalDate.of(), — это соглашение об именовании, а не паттерн GoF. Паттерн GoF использует наследование, а статические фабрики — статические методы одного класса.
// Static factory (NOT the GoF pattern)
LocalDate d = LocalDate.of(2024, 6, 15);
// GoF Factory Method uses a class hierarchyФабричный метод с параметром
Передайте параметр фабричному методу, чтобы выбирать один из нескольких продуктов без создания отдельного подкласса для каждого продукта.
public class ShapeFactory {
public static Shape create(String type, double... dims) {
return switch (type) {
case "circle" -> new Circle(dims[0]);
case "rectangle" -> new Rectangle(dims[0], dims[1]);
default -> throw new IllegalArgumentException("Unknown: " + type);
};
}
}Фабричный метод с обобщениями
Используйте обобщения, чтобы сделать фабричный метод типобезопасным и пригодным для повторного использования в разных семействах продуктов.
public abstract class Repository<T, ID> {
public abstract T findById(ID id);
protected abstract T createEmpty(); // factory method
}Регистрация фабрик с помощью карты
Фабрика на основе реестра хранит карту строковых типов и лямбда-выражений Supplier, избегая цепочек if-else и обеспечивая динамическую регистрацию.
Map<String, Supplier<Notification>> registry = new HashMap<>();
registry.put("email", EmailNotification::new);
registry.put("sms", SmsNotification::new);
Notification n = registry.getOrDefault(type, DefaultNotification::new).get();Фабричный метод и абстрактная фабрика
Фабричный метод создаёт один тип продукта с помощью наследования. Абстрактная фабрика создаёт семейства связанных продуктов с помощью композиции. Используйте фабричный метод, когда изменяется один продукт, а абстрактную фабрику — когда всё семейство изменяется согласованно.
Пример из реального мира: фабрика регистраторов
Статическая фабрика SLF4J LoggerFactory.getLogger(Class) возвращает подходящую реализацию регистратора (Logback, Log4j, JUL), не требуя от вызывающего кода знать, какая именно реализация используется.
Logger log = LoggerFactory.getLogger(MyService.class);
log.info("Service started");Быстрая проверка
Какова ключевая особенность паттерна «Фабричный метод»?
Итоги
Фабричный метод отделяет создание объектов от клиента, помещая решение о создании экземпляра в переопределяемые методы подклассов. Используйте его, когда класс не может заранее определить, какие объекты ему потребуется создавать.
Часто задаваемые вопросы
Урок «Шаблон фабричного метода» бесплатный?
Да — полный текст урока «Шаблон фабричного метода» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Шаблон фабричного метода»?
Определяйте фабричный метод в базовом классе и позволяйте подклассам решать, какой продукт создавать. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Шаблон фабричного метода»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Singleton: потокобезопасные реализации
- Шаблон фабричного метода
- Абстрактная фабрика для семейств продуктов
- Шаблон Builder с плавным API