Ответ
Factory Method — это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов.
Цель: Инкапсулировать логику создания объектов, делая систему независимой от конкретных классов продуктов.
Преимущества:
- Изоляция кода создания: Клиентский код работает с интерфейсом, а не с конкретными классами.
- Принцип открытости/закрытости: Легко добавить новый тип продукта, создав новый подкласс фабрики.
- Упрощение тестирования: Фабрику можно подменить заглушкой (Mock).
Пример на Java:
// 1. Общий интерфейс продукта
interface Transport {
void deliver();
}
// 2. Конкретные продукты
class Truck implements Transport {
@Override
public void deliver() {
System.out.println("Доставка груза по дороге.");
}
}
class Ship implements Transport {
@Override
public void deliver() {
System.out.println("Доставка груза по морю.");
}
}
// 3. Базовый класс фабрики (создатель)
abstract class Logistics {
// Фабричный метод
abstract Transport createTransport();
// Бизнес-логика, использующая продукт
public void planDelivery() {
Transport transport = createTransport();
transport.deliver();
}
}
// 4. Конкретные создатели
class RoadLogistics extends Logistics {
@Override
Transport createTransport() {
return new Truck();
}
}
class SeaLogistics extends Logistics {
@Override
Transport createTransport() {
return new Ship();
}
}
// 5. Использование
public class Demo {
public static void main(String[] args) {
Logistics logistics = new RoadLogistics();
logistics.planDelivery(); // Создаст Truck и вызовет его deliver()
}
} Ответ 18+ 🔞
Да ты посмотри, какой народ безмозглый, блядь! Опять про эти ваши паттерны. Ну ладно, разберём, как есть.
Вот есть у тебя, допустим, задача — создавать объекты. А объекты-то разные, ёпта! Грузовик, корабль, самолёт. И логика создания у них — пиздец какая разная. Можно, конечно, везде натыкать new Truck() и new Ship(), но тогда твой код превратится в такой монолит, что его потом раздолбать будет — овердохуища работы.
Так вот, умные дядьки придумали Factory Method, чтобы эту поебень инкапсулировать. Суть проста, как три копейки: ты выносишь всю возню с new в отдельный метод, который живёт в своём собственном классе-создателе. А главный код даже не в курсе, какой конкретно объект создаётся — он работает с интерфейсом.
Нахуя это надо?
- Клиентский код не парится. Ему похуй, грузовик там или подводная лодка. Он знает только, что у объекта есть метод
deliver(), и он его вызывает. Всё. - Легко добавить новую хуйню. Надо новый транспорт? Создаёшь новый класс продукта и новый класс логистики для него. Старый код даже не чихнёт. Принцип открытости/закрытости в действии, блядь!
- Тестировать — одно удовольствие. Подсовываешь в тестах свою фабрику-заглушку, которая создаёт не настоящий грузовик, а какую-нибудь муляжную хрень, и проверяешь логику. Красота!
Смотри, как это в коде выглядит, на примере доставки:
// 1. Интерфейс для всего, что может доставлять
interface Transport {
void deliver();
}
// 2. Конкретные виды доставки
class Truck implements Transport {
@Override
public void deliver() {
System.out.println("Тащу твой хлам по дороге, как последний лох.");
}
}
class Ship implements Transport {
@Override
public void deliver() {
System.out.println("Плыву по морю, волны бьют, доставка долгая, терпи, мудак.");
}
}
// 3. Абстрактная фабрика (создатель). Вот где магия!
abstract class Logistics {
// Вот он, ёбаный фабричный метод! Конкретная реализация — в наследниках.
abstract Transport createTransport();
// А это бизнес-логика, которая этим методом пользуется
public void planDelivery() {
Transport transport = createTransport(); // Создаём что-то, хз что
transport.deliver(); // А вот это что-то — доставляет!
}
}
// 4. Конкретные фабрики. Каждая знает, какую конкретную хуйню создавать.
class RoadLogistics extends Logistics {
@Override
Transport createTransport() {
return new Truck(); // Дорога? Значит, грузовик!
}
}
class SeaLogistics extends Logistics {
@Override
Transport createTransport() {
return new Ship(); // Море? Окей, кораблик.
}
}
// 5. Использование
public class Demo {
public static void main(String[] args) {
Logistics logistics = new RoadLogistics(); // Говорим: "Хочу дорожную логистику!"
logistics.planDelivery(); // А внутри само создаст грузовик и пошлёт его в путь. В рот меня чих-пых!
}
}
Вот и вся философия. Вместо того чтобы самому везде лезть с new, ты делегируешь это дело специальному классу. Получается аккуратно, расширяемо и без лишней головной боли. Ну а если не использовать — потом сам будешь, как Герасим, только «Му-му» говорить, когда систему расширять придётся.