BehavioralPythonverifiedVerified
Mediator Pattern in Python
Defines an object that encapsulates how a set of objects interact, promoting loose coupling by keeping objects from referring to each other explicitly.
How to Implement the Mediator Pattern in Python
1Step 1: Define the Mediator interface and participant base class
from __future__ import annotations
from typing import Protocol
class Mediator(Protocol):
def notify(self, sender: "ChatParticipant", message: str) -> None: ...
class ChatParticipant:
def __init__(self, name: str, mediator: Mediator) -> None:
self.name = name
self._mediator = mediator
def send(self, message: str) -> None:
print(f"[{self.name}] sends: {message}")
self._mediator.notify(self, message)
def receive(self, from_name: str, message: str) -> None:
print(f"[{self.name}] received from {from_name}: {message}")2Step 2: Implement the ChatRoom as a concrete mediator
class ChatRoom:
def __init__(self) -> None:
self._participants: list[ChatParticipant] = []
def join(self, participant: ChatParticipant) -> None:
self._participants.append(participant)
def notify(self, sender: ChatParticipant, message: str) -> None:
for participant in self._participants:
if participant is not sender:
participant.receive(sender.name, message)3Step 3: Connect participants and exchange messages
room = ChatRoom()
alice = ChatParticipant("Alice", room)
bob = ChatParticipant("Bob", room)
carol = ChatParticipant("Carol", room)
room.join(alice)
room.join(bob)
room.join(carol)
alice.send("Hello everyone!")"""Form Validation Mediator coordinating cross-field validation."""
from dataclasses import dataclass, field
from typing import Callable
import re
# [step] Define validation rule and field state types
ValidationRule = Callable[[str], str | None]
@dataclass
class FieldState:
value: str = ""
errors: list[str] = field(default_factory=list)
is_dirty: bool = False
is_valid: bool = False
# [step] Implement the FormField component
class FormField:
def __init__(
self,
name: str,
mediator: "RegistrationFormMediator",
rules: list[ValidationRule],
) -> None:
self.name = name
self._mediator = mediator
self._rules = rules
self._state = FieldState()
def set_value(self, value: str) -> None:
self._state.value = value
self._state.is_dirty = True
self._mediator.field_changed(self.name, value)
def validate(self) -> list[str]:
return [
msg for rule in self._rules
if (msg := rule(self._state.value)) is not None
]
def set_state(self, **kwargs) -> None:
for key, value in kwargs.items():
setattr(self._state, key, value)
@property
def state(self) -> FieldState:
return self._state
# [step] Define common validation rules
def required(value: str) -> str | None:
return None if value.strip() else "This field is required"
def email_rule(value: str) -> str | None:
return None if re.match(r"^[^\s@]+@[^\s@]+\.[^\s@]+$", value) else "Invalid email address"
def min_length(minimum: int) -> ValidationRule:
def validate(value: str) -> str | None:
return None if len(value) >= minimum else f"Minimum {minimum} characters required"
return validate
# [step] Implement the form mediator with cross-field coordination
class RegistrationFormMediator:
def __init__(self) -> None:
self._fields: dict[str, FormField] = {}
def register(self, field: FormField) -> None:
self._fields[field.name] = field
def field_changed(self, field_name: str, value: str) -> None:
field = self._fields.get(field_name)
if field is None:
return
errors = field.validate()
field.set_state(errors=errors, is_valid=len(errors) == 0)
if field_name in ("password", "confirm_password"):
self._validate_password_match()
def _validate_password_match(self) -> None:
password = self._fields.get("password")
confirm = self._fields.get("confirm_password")
if not password or not confirm:
return
if not confirm.state.is_dirty:
return
match = password.state.value == confirm.state.value
base_errors = confirm.validate()
extra = [] if match else ["Passwords do not match"]
confirm.set_state(
errors=base_errors + extra,
is_valid=len(base_errors) == 0 and match,
)
def is_form_valid(self) -> bool:
return all(f.state.is_valid for f in self._fields.values())
# [step] Set up the form
mediator = RegistrationFormMediator()
email_field = FormField("email", mediator, [required, email_rule])
password_field = FormField("password", mediator, [required, min_length(8)])
confirm_field = FormField("confirm_password", mediator, [required])
mediator.register(email_field)
mediator.register(password_field)
mediator.register(confirm_field)Mediator Pattern Architecture
hourglass_empty
Rendering diagram...
lightbulb
Mediator Pattern in the Real World
“An air traffic control tower is the classic example. Instead of every plane communicating directly with every other plane—a chaotic and dangerous mess—all aircraft talk only to the control tower. The tower mediates all interactions, directing each plane based on the overall picture it maintains. Planes are decoupled from each other entirely.”