Mediator Pattern — Design Patterns

Mediator menengahi komunikasi antar-object. Daripada N object berkomunikasi langsung (N² edge), semua berkomunikasi lewat satu pusat → N edge saja. Masalah tanp

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:

Kekurangan:

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:

Jadi kamu mungkin sudah pakai Mediator tanpa sadar!