Mediator menengahi komunikasi antar-object. Daripada N object berkomunikasi langsung (N² edge), semua berkomunikasi lewat satu pusat → N edge saja.
Masalah tanpa Mediator:
ButtonLogin ──► InputEmail ──► Validator ──► SubmitButton
│ ▲ │ ▲
└─────────────────┴──────────────┴──────────────┘
(N komponen → N² relasi, susah di-track dan di-test)
Dengan Mediator:
ButtonLogin ──┐ ┌──► InputEmail
▼ │
Mediator ◄──► Validator
▲ │
SubmitButton ─┘ └──► ErrorDisplay
Setiap komponen hanya tahu Mediator. Mediator yang tahu siapa harus diberi tahu saat event terjadi.
Contoh: form dialog complex
class FormMediator {
constructor() {
this.components = {};
}
register(name, component) {
this.components[name] = component;
component.mediator = this;
}
notify(sender, event) {
if (sender === "emailInput" && event === "changed") {
const valid = this.components.validator.check(sender.value);
this.components.submitBtn.setEnabled(valid);
this.components.errorLabel.setText(valid ? "" : "Email invalid");
}
if (sender === "submitBtn" && event === "clicked") {
const data = {
email: this.components.emailInput.value,
password: this.components.passwordInput.value,
};
this.components.apiClient.submit(data);
}
}
}
Mediator vs Pub/Sub:
| Aspek | Mediator | Pub/Sub |
|---|---|---|
| Coupling | Sender tahu mediator | Sender tidak tahu subscribers |
| Topology | Centralized (1 hub) | Distributed (multi topic) |
| Logika | Smart coordinator | Dumb broker |
| Use case | Form, dialog, UI component | Event bus, microservices |
Air traffic control — contoh klasik:
Pesawat tidak berkomunikasi satu sama lain. Mereka bicara ke Tower (Mediator). Tower yang tahu siapa di mana, siapa perlu delay, siapa dapat runway mana.
React + Context sebagai Mediator informal:
const FormContext = createContext();
function FormProvider({ children }) {
const [state, dispatch] = useReducer(formReducer, initialState);
// Mediator = reducer + context
return (
<FormContext.Provider value={{ state, dispatch }}>
{children}
</FormContext.Provider>
);
}
// Komponen tidak saling tahu — semua pakai context
function EmailInput() {
const { state, dispatch } = useContext(FormContext);
return <input onChange={e => dispatch({ type: "SET_EMAIL", value: e.target.value })} />;
}
Kelebihan:
- Decoupling komponen → bisa di-test isolasi
- Satu tempat untuk mengatur coordination logic
- Mudah tambah komponen baru tanpa edit yang lama
Kekurangan:
- Mediator bisa jadi "God class" kalau logika terlalu banyak
- Debugging: alur tidak langsung (cek mediator untuk tahu flow)
- Performance: semua event lewat satu hub (biasanya OK)
Anti-pattern: Mediator terlalu gemuk
Jika mediator punya 500 baris dan tahu semua detail implementasi komponen → itu tanda komponen terlalu terikat secara logika. Pecah jadi sub-mediator per concern.
Implementasi modern:
Banyak state management library (Redux, Zustand, Pinia) secara efektif adalah Mediator:
- Store = Mediator
- Actions = message ke Mediator
- Mediator yang update state dan notify subscribers
Jadi kamu mungkin sudah pakai Mediator tanpa sadar!