// Design Patterns · 17
Mediator
Route interactions through one object instead of a web of calls.
How it fits together
- CheckoutFormMediator implements CheckoutMediator
- CountryPicker publishes / notifies CheckoutFormMediator (1 changed)
- CheckoutFormMediator uses / calls ShippingOptions (2 reload)
- ShippingOptions publishes / notifies CheckoutFormMediator (3 changed)
- CheckoutFormMediator uses / calls PaymentMethods (4 reload)
Spot it
- Every widget references every other widget
- Changing one component breaks three others
- Interaction rules scattered across classes
It costs
Coupling moves into the mediator, which can grow into a god object.
In code
public interface ICheckoutMediator{ Task ChangedAsync(object sender, CancellationToken ct);}public sealed class CheckoutFormMediator( CountryPicker country, ShippingOptions shipping, PaymentMethods payment) : ICheckoutMediator{ public async Task ChangedAsync(object sender, CancellationToken ct) { switch (sender) { case CountryPicker: await shipping.ReloadAsync(country.Selected, ct); break; case ShippingOptions: await payment.ReloadAsync(country.Selected, shipping.Selected, ct); break; } }}Go deeperThe full explanation and what to ask for · 1 min readExpandCollapse
A mediator encapsulates how a set of objects interact. Colleagues no longer reference each other; they tell the mediator that something happened, and it decides who reacts. A many-to-many web becomes one-to-many, and the interaction rules live in one place.
The mediator concentrates coupling rather than removing it, so keep it to coordination and push real work back into the colleagues. A single application-wide dispatcher that routes every request is a different thing, an in-process message bus, which hides call paths without adding this kind of coordination.
Observer distributes communication: a subject broadcasts and anyone may subscribe, with nobody owning the rules. Mediator centralises it: one object knows the colleagues and the order of reactions, often receiving their notifications observer-style. Facade also fronts several objects, but they do not know it exists and calls flow one way.
Ask for it
- mediator
- colleague
- many-to-many → one-to-many
- coordination logic
- event aggregator
In the checkout form, the country, shipping and payment components update each other directly. Add a CheckoutMediator that each component notifies with Changed(sender), and let it decide what to reload (country → shipping options → payment methods). Components may only reference the mediator.