Ответ
Factory (Фабрика) — это общее название для группы порождающих паттернов, которые инкапсулируют логику создания объектов. Чаще всего под "простой фабрикой" понимают Simple Factory (статический метод-фабрика), который не является отдельным паттерном из GoF, но широко используется.
Factory Method (Фабричный метод) — это конкретный паттерн проектирования из книги GoF, где создание объекта делегируется подклассам.
1. Simple Factory (Простая фабрика)
Это класс с методом (часто статическим), который на основе входного параметра создает и возвращает объект нужного типа.
interface Transport {
void deliver();
}
class Truck implements Transport {
public void deliver() { System.out.println("Deliver by land"); }
}
class Ship implements Transport {
public void deliver() { System.out.println("Deliver by sea"); }
}
// Простая фабрика (не GoF паттерн)
class TransportFactory {
public static Transport createTransport(String type) {
return switch (type.toLowerCase()) {
case "truck" -> new Truck();
case "ship" -> new Ship();
default -> throw new IllegalArgumentException("Unknown transport");
};
}
}
// Использование
Transport t = TransportFactory.createTransport("truck");
t.deliver();
Недостаток Simple Factory: При добавлении нового типа (Plane) необходимо изменять метод createTransport, нарушая принцип открытости/закрытости (OCP).
2. Factory Method (Фабричный метод, паттерн GoF)
Определяет абстрактный метод для создания объекта, но оставляет реализацию этого метода подклассам. Каждый подкласс решает, какой конкретный объект создать.
// Абстрактный создатель (Creator)
abstract class Logistics {
// Фабричный метод
abstract Transport createTransport();
// Бизнес-логика, использующая продукт
public void planDelivery() {
Transport t = createTransport(); // Вызов фабричного метода
t.deliver();
}
}
// Конкретные создатели
class RoadLogistics extends Logistics {
@Override
Transport createTransport() {
return new Truck(); // Решает, какой объект создать
}
}
class SeaLogistics extends Logistics {
@Override
Transport createTransport() {
return new Ship();
}
}
// Использование
Logistics logistics = new RoadLogistics();
logistics.planDelivery(); // Будет создан и использован Truck
| Ключевые отличия: | Аспект | Simple Factory | Factory Method (GoF) |
|---|---|---|---|
| Суть | Класс с методом, создающим объекты. | Делегирование создания подклассам через абстрактный метод. | |
| Расширяемость | Нарушает OCP (требует изменения фабрики). | Соблюдает OCP (новый тип = новый подкласс Creator). | |
| Связность | Централизованная логика создания. | Логика создания распределена по иерархии классов. | |
| Цель | Сокрытие логики инстанцирования. | Позволить подклассам решать, какой объект создавать. |
Вывод: Factory Method — это более гибкий и полиморфный паттерн, который следует принципам OCP, в то время как Simple Factory — это простой и полезный идиоматический прием для инкапсуляции создания объектов.
Ответ 18+ 🔞
Слушай, а давай разберёмся, что за фабрики такие, а то все ими кидаются, а толком объяснить не могут. Вот представь, что ты на стройке, и тебе нужен инструмент. Можно, конечно, самому каждый раз бегать на склад, искать нужную дрель, но это же, блядь, неудобно! Вот для этого и придумали фабрики — чтобы тебе просто сказали «дай дрель», а тебе её уже принесли, готовую.
Simple Factory (Простая фабрика) — это как будто у тебя есть один универсальный снабженец Вася. Ты ему кричишь: «Вася, дай мне грузовик!». А Вася такой: «Ща, браток», — идёт на склад и привозит тебе этот самый грузовик. Всё просто, понятно, но есть одна, сука, проблема. Если завтра тебе понадобится самолёт, а Вася про самолёты нихуя не знает, придётся его самого переучивать, лезть ему в мозги и менять его инструкции. Нарушается принцип «открытости/закрытости» — чтобы добавить что-то новое, надо ковырять существующий код. Не очень-то гибко, правда?
// Вот этот Вася, наш снабженец
class TransportFactory {
public static Transport createTransport(String type) {
if (type.equalsIgnoreCase("truck")) {
return new Truck(); // Привёз грузовик
} else if (type.equalsIgnoreCase("ship")) {
return new Ship(); // Привёг корабль
} else {
throw new IllegalArgumentException("Чё те надо, мудила? Такого у нас нет!");
}
}
}
// А пользоваться просто:
Transport t = TransportFactory.createTransport("truck");
t.deliver(); // Поехали!
Factory Method (Фабричный метод, тот самый паттерн из книжки) — это уже поумнее. Тут нет одного Васю. Тут у тебя есть начальник отдела логистики, который говорит: «Ребята, план доставки у нас такой-то, а кто и на чём повезёт — решайте сами на местах!».
То есть создаётся абстрактный класс-родитель, который объявляет: «Эй, потомки, у вас будет метод createTransport(), но как вы его реализуете — это ваши, блядь, проблемы!».
// Абстрактный начальник, который знает план, но не лезет в детали
abstract class Logistics {
// Вот он, фабричный метод! Конкретики нет.
abstract Transport createTransport();
// А вот бизнес-логика, которая этим пользуется
public void planDelivery() {
Transport t = createTransport(); // Надеется на потомков
t.deliver();
}
}
// А вот конкретные исполнители. Дорожники знают своё дело.
class RoadLogistics extends Logistics {
@Override
Transport createTransport() {
return new Truck(); // «Нам грузовик подавай!»
}
}
// Моряки — своё.
class SeaLogistics extends Logistics {
@Override
Transport createTransport() {
return new Ship(); // «Нам корабль, ёпта!»
}
}
// Используем:
Logistics logistics = new RoadLogistics();
logistics.planDelivery(); // Всё работает, создался Truck
Так в чём, блядь, разница, спросишь ты? Да в том, кто принимает решение!
- Simple Factory: Решение принимает один центральный орган (наш Вася-фабрика) на основе какого-то параметра (строки, enum). Добавить новый тип — пойти и переписать Васину инструкцию. Нарушается OCP.
- Factory Method: Решение принимают конкретные классы-наследники. Каждый сам решает, что ему создавать. Хочешь добавить воздушную логистику? Просто создаёшь новый класс
AirLogistics, который возвращаетnew Plane(). Основной классLogisticsи остальной код даже не узнают об этом! Это и есть соблюдение OCP — система открыта для расширения, но закрыта для модификации.
Вывод, ёпта: Simple Factory — это просто удобная обёртка для создания объектов, как костыль, который всем виден. А Factory Method — это уже продуманная архитектура, где создание объектов делегировано полиморфно, и система может расти, не ломая уже работающее. Выбирай, что тебе больше подходит, но не путай одно с другим, а то получится пиздопроебищно!