Ответ
Паттерн Медиатор (Mediator) — это поведенческий паттерн проектирования, который устраняет сильную связанность между объектами (компонентами), заставляя их взаимодействовать через центральный объект-посредник («медиатор»).
Проблема, которую решает: Когда в системе много компонентов, которые должны взаимодействовать друг с другом, это приводит к сложной сети прямых связей («спагетти-код»). Каждый компонент должен знать о многих других, что затрудняет его изменение и переиспользование.
Решение: Медиатор инкапсулирует всю логику взаимодействия. Компоненты больше не ссылаются друг на друга, а только на медиатор. Они отправляют уведомления медиатору, а он уже решает, кому их перенаправить.
Ключевые преимущества:
- Слабая связанность (Low Coupling): Компоненты не зависят друг от друга.
- Централизованное управление: Логика взаимодействия находится в одном месте.
- Упрощение поддержки: Легче изменять поведение системы, модифицируя только медиатор.
- Повышение переиспользуемости: Отдельные компоненты проще использовать в других контекстах.
Пример на Python:
from abc import ABC, abstractmethod
# Интерфейс Медиатора
class Mediator(ABC):
@abstractmethod
def notify(self, sender: object, event: str) -> None:
pass
# Базовый Компонент
class BaseComponent:
def __init__(self, mediator: Mediator = None):
self._mediator = mediator
@property
def mediator(self) -> Mediator:
return self._mediator
@mediator.setter
def mediator(self, mediator: Mediator) -> None:
self._mediator = mediator
# Конкретные Компоненты
class ComponentA(BaseComponent):
def do_work(self):
print("Компонент A выполняет действие и уведомляет медиатора.")
self.mediator.notify(self, "EventA")
class ComponentB(BaseComponent):
def react_on_a(self):
print("Компонент B реагирует на событие A.")
def react_on_c(self):
print("Компонент B реагирует на событие C.")
class ComponentC(BaseComponent):
def do_another_work(self):
print("Компонент C выполняет действие и уведомляет медиатора.")
self.mediator.notify(self, "EventC")
# Конкретный Медиатор
class ConcreteMediator(Mediator):
def __init__(self, component_a: ComponentA, component_b: ComponentB, component_c: ComponentC):
self._component_a = component_a
self._component_a.mediator = self
self._component_b = component_b
self._component_b.mediator = self
self._component_c = component_c
self._component_c.mediator = self
def notify(self, sender: object, event: str) -> None:
if event == "EventA":
print("Медиатор получил событие от A и передает его B.")
self._component_b.react_on_a()
elif event == "EventC":
print("Медиатор получил событие от C и передает его B.")
self._component_b.react_on_c()
# Использование
c1 = ComponentA()
c2 = ComponentB()
c3 = ComponentC()
mediator = ConcreteMediator(c1, c2, c3)
c1.do_work()
print("-" * 20)
c3.do_another_work() Ответ 18+ 🔞
О, паттерн Медиатор, ёпта! Это ж как раз про то, когда у тебя в проекте компоненты начинают друг друга знать настолько, что превращаются в одну большую, блядь, семью — где все друг другу троюродные племянники и постоянно звонят по любому поводу.
Суть проблемы, которую он решает, проще говоря:
Представь, что у тебя есть три класса: Кнопка, Поле ввода и Список. И они все должны друг с другом общаться. Кнопка нажалась — надо Поле очистить и Список обновить. Поле изменилось — надо Кнопку заблокировать. В итоге ты пишешь в коде Кнопки вызовы методов и Поля, и Списка. Получается пиздец какой спагетти-код, где всё завязано на всё. Хули один компонент знает про внутренности другого? Это же пиздец как негибко! Захотел Список заменить на Таблицу — придётся во всех остальных классах ковыряться. Терпения ноль, ебать!
А решение-то какое, блядь?
А решение — впендюрить между ними ещё одного чувака, Медиатора. Это такой центральный диспетчер, почтальон, ёбаный в рот. Теперь наши Кнопка, Поле и Список нихуя не знают друг о друге. Они знают только этого медиатора. Сделал что-то — крикнул медиатору: «Эй, я, Кнопка, только что нажался, событие такое-то!». А медиатор уже сам решает, кому и что передать: «Ага, Кнопка нажалась — значит, Поле, чисться, а Список, обновляйся, пидары!». Всё, связанность упала до плинтуса.
Что хорошего-то, спрашиваешь?
- Слабая связанность, мать его. Компоненты становятся независимыми идиотами, которые только умеют своё дело делать и орать медиатору. Их теперь можно таскать в другие проекты, как чемоданы.
- Вся хуйня в одном месте. Вся логика «кто кому что должен сказать» сидит в медиаторе. Захотел поменять поведение — идёшь в один класс, а не в двадцать.
- Поддержка проще. Не надо рыться во всём коде, чтобы понять, почему
Полеочищается при нажатииКнопки. Всё написано в медиаторе, как на ладони.
А вот тебе пример на Python, чтобы совсем понятно стало. Блок кода не трогаю, он святой:
from abc import ABC, abstractmethod
# Интерфейс Медиатора
class Mediator(ABC):
@abstractmethod
def notify(self, sender: object, event: str) -> None:
pass
# Базовый Компонент
class BaseComponent:
def __init__(self, mediator: Mediator = None):
self._mediator = mediator
@property
def mediator(self) -> Mediator:
return self._mediator
@mediator.setter
def mediator(self, mediator: Mediator) -> None:
self._mediator = mediator
# Конкретные Компоненты
class ComponentA(BaseComponent):
def do_work(self):
print("Компонент A выполняет действие и уведомляет медиатора.")
self.mediator.notify(self, "EventA")
class ComponentB(BaseComponent):
def react_on_a(self):
print("Компонент B реагирует на событие A.")
def react_on_c(self):
print("Компонент B реагирует на событие C.")
class ComponentC(BaseComponent):
def do_another_work(self):
print("Компонент C выполняет действие и уведомляет медиатора.")
self.mediator.notify(self, "EventC")
# Конкретный Медиатор
class ConcreteMediator(Mediator):
def __init__(self, component_a: ComponentA, component_b: ComponentB, component_c: ComponentC):
self._component_a = component_a
self._component_a.mediator = self
self._component_b = component_b
self._component_b.mediator = self
self._component_c = component_c
self._component_c.mediator = self
def notify(self, sender: object, event: str) -> None:
if event == "EventA":
print("Медиатор получил событие от A и передает его B.")
self._component_b.react_on_a()
elif event == "EventC":
print("Медиатор получил событие от C и передает его B.")
self._component_b.react_on_c()
# Использование
c1 = ComponentA()
c2 = ComponentB()
c3 = ComponentC()
mediator = ConcreteMediator(c1, c2, c3)
c1.do_work()
print("-" * 20)
c3.do_another_work()
Видишь, как оно работает? ComponentA делает своё дело и орёт медиатору. Медиатор, этот хитрая жопа, смотрит: «А, событие EventA — значит, надо ComponentB пнуть, чтобы он среагировал». И пиздык — ComponentB выполняет react_on_a(). Никаких прямых связей, один сплошной порядок, ебать мои старые костыли! Красота же.