Ответ
Паттерн 'Фабричный метод' (Factory Method) — это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов, но позволяет подклассам изменять тип создаваемых объектов.
Основная цель — делегировать создание объектов от клиентского кода к дочерним классам. Это позволяет вводить новые типы продуктов, не изменяя код, который эти продукты использует.
Ключевые преимущества:
- Инкапсуляция: Логика создания объектов скрыта от клиента.
- Гибкость: Легко добавлять новые типы создаваемых объектов (продуктов), просто создав новый класс-создатель.
- Слабая связанность: Клиентский код работает с абстрактным интерфейсом продукта, а не с его конкретной реализацией.
Пример на Python:
from abc import ABC, abstractmethod
# Интерфейс Продукта
class Transport(ABC):
@abstractmethod
def deliver(self) -> str:
pass
# Конкретные Продукты
class Truck(Transport):
def deliver(self) -> str:
return "Доставка грузовиком по земле"
class Ship(Transport):
def deliver(self) -> str:
return "Доставка кораблем по морю"
# Абстрактный Создатель (Фабрика)
class Logistics(ABC):
@abstractmethod
def create_transport(self) -> Transport:
# Это и есть Фабричный метод
pass
def plan_delivery(self) -> str:
transport = self.create_transport()
return f"Логистика: {transport.deliver()}"
# Конкретные Создатели
class RoadLogistics(Logistics):
def create_transport(self) -> Transport:
return Truck()
class SeaLogistics(Logistics):
def create_transport(self) -> Transport:
return Ship()
# Клиентский код
road_logistics = RoadLogistics()
print(road_logistics.plan_delivery()) # Вывод: Логистика: Доставка грузовиком по земле
sea_logistics = SeaLogistics()
print(sea_logistics.plan_delivery()) # Вывод: Логистика: Доставка кораблем по морю Ответ 18+ 🔞
Давай разберём этот ваш паттерн «Фабричный метод», а то смотрю — народ путается, как мухи в паутине. Ну, типа, представь себе, что ты — главный по логистике, царь и бог, который решает, какую хуйню куда везти.
Вот сидишь ты такой и думаешь: «Бля, надо груз отправить. Но ёпта, если по земле — то грузовик, а если по морю — то корабль, а если по воздуху — то самолёт, а это уже другая история, в рот меня чих-пых!». И каждый раз в коде писать if transport_type == "truck": ... elif transport_type == "ship": ... — это же пиздец какой-то, правда? Код превращается в лапшу, в которой через месяц сам чёрт ногу сломит.
Вот тут-то и выручает Фабричный метод. Суть его, блядь, проще пареной репы, хоть и звучит умно.
Чё он делает? Он говорит: «Слушай, дружок-пирожок. Не парься, какой именно объект создавать. Просто скажи, что тебе нужен некий «Транспорт», а уж я сам разберусь, грузовик это будет или пароход».
Как это работает, ёпта?
- Продукт (Transport): Сначала ты объявляешь общий интерфейс для всей своей ездящей-плавающей братвы. Грузовик, корабль, велосипед — всем им надо уметь доставлять херню. У всех будет метод
deliver(). - Конкретные продукты (Truck, Ship): Это уже реальные тачки. Грузовик доставляет по земле, корабль — по воде. Каждый из них реализует этот самый
deliver()по-своему. - Создатель (Logistics): А это — мозг операции. Абстрактный такой чувак, который знает алгоритм работы (спланировать доставку —
plan_delivery()), но не знает конкретики. У него есть один абстрактный метод —create_transport(). Это и есть тот самый фабричный метод, ёбана! - Конкретные создатели (RoadLogistics, SeaLogistics): А вот ихние сыновья уже решают. Один говорит: «А я создаю только грузовики!». Другой: «А я — только корабли!». Они реализуют этот фабричный метод и возвращают нужный объект.
И что в итоге?
А в итоге клиентский код (то есть ты) работает не с кучей if-ов, а с абстракцией. Хочешь доставку по дороге? Берёшь RoadLogistics и вызываешь plan_delivery(). Он внутри сам, хитрая жопа, вызовет свой фабричный метод, создаст грузовик и всё организует. Захотел морем — взял SeaLogistics. Добавить новый вид транспорта? Да хуй с ним! Создал новый класс продукта (например, Drone) и новый класс создателя (типа AirLogistics), который этот дрон и возвращает. Основной код логики доставки (plan_delivery) менять не надо вообще, ни хуя!
Преимущества, блядь:
- Чистота: Клиент не засран проверками типов.
- Гибкость: Новый транспорт добавляется проще, чем я это объясняю. Создал два новых класса — и вперёд.
- Слабая связность: Клиент привязан к интерфейсу
Transport, а не к конкретным классам грузовиков и кораблей. Это охуенно.
Вот тебе живой пример на Python, смотри:
from abc import ABC, abstractmethod
# 1. Интерфейс Продукта - что должен уметь любой транспорт?
class Transport(ABC):
@abstractmethod
def deliver(self) -> str:
pass
# 2. Конкретные Продукты - реальные тачки
class Truck(Transport):
def deliver(self) -> str:
return "Доставка грузовиком по земле"
class Ship(Transport):
def deliver(self) -> str:
return "Доставка кораблем по морю"
# 3. Абстрактный Создатель (Фабрика) - знает процесс, но не детали
class Logistics(ABC):
@abstractmethod
def create_transport(self) -> Transport: # <--- Вот он, ёбаный фабричный метод!
pass
def plan_delivery(self) -> str: # А это общий алгоритм, который не меняется
transport = self.create_transport() # Создаём транспорт (какой? хз!)
return f"Логистика: {transport.deliver()}" # Работаем с ним
# 4. Конкретные Создатели - они-то и знают, какую конкретно хуйню создавать
class RoadLogistics(Logistics):
def create_transport(self) -> Transport:
return Truck() # "Я создаю только грузовики, нахуй!"
class SeaLogistics(Logistics):
def create_transport(self) -> Transport:
return Ship() # "А я — только корабли, в рот меня чих-пых!"
# 5. Клиентский код - использует абстракции и не парится
road_logistics = RoadLogistics()
print(road_logistics.plan_delivery()) # Вывод: Логистика: Доставка грузовиком по земле
sea_logistics = SeaLogistics()
print(sea_logistics.plan_delivery()) # Вывод: Логистика: Доставка кораблем по морю
Короче, паттерн — огонь. Позволяет отвязать создание объектов от их использования. Как будто у тебя есть универсальный пульт (создатель), а ты просто меняешь в нём батарейки (конкретные классы), чтобы он управлял то телевизором, то кондиционером. Красота, ёпта!