Skip to content

Mediator

The Mediator pattern is similar to the Observer pattern in that it describes how to execute requests and its handling. This pattern is worth applying when in the application we find many components that somehow communicate with each other. When the relationships between them become complicated, for example:

no_mediator

then consider using this pattern.

The mediator is an additional object that is inserted between all these components, instead of communicating with each other directly, they communicate only with him:

mediator

This approach allows reducing the number of dependencies between objects.

Example

The example simulates simple dependencies between graphic components. Updating one of them (e.g. by the user's selection), updates some of them. All communication is through one 'Mediator':

public interface Component {
  void sendRequest();

  default void sendRequest(String context) {
    sendRequest();
  }
}
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ActionAppliedMessage implements Component {

  private Mediator mediator;

  public void setMediator(final Mediator mediator) {
    this.mediator = mediator;
  }

  public void displayInfo() {
    log.info("Action was applied successfully");
  }

  @Override
  public void sendRequest() {
    mediator.sendInfo(this, "ActionAppliedMessage");
  }
}
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SelectOptions implements Component {

  private Mediator mediator;

  public void setMediator(final Mediator mediator) {
    this.mediator = mediator;
  }

  public void displayOptions() {
    log.info("Options are: Save, Load, Restart");
  }

  public void chooseSave() {
    log.info("Status was saved");
  }

  public void chooseLoad() {
    log.info("Loading previous data");
  }

  public void chooseRestart() {
    log.info("Status is restarting");
  }

  public void hideOptions() {
    log.info("Hiding options");
  }

  @Override
  public void sendRequest() {
    mediator.sendInfo(this, "displayOptions");
  }

  @Override
  public void sendRequest(final String context) {
    mediator.sendInfo(this, context);
  }
}
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class WarningMessage implements Component {

  private Mediator mediator;

  public void setMediator(final Mediator mediator) {
    this.mediator = mediator;
  }

  public void showWarningMessage() {
    log.warn("Are you sure?");
  }

  public void hideWarning() {
    log.warn("");
  }

  @Override
  public void sendRequest() {
    mediator.sendInfo(this, "WarningMessage");
  }
}
public interface Mediator {
  void sendInfo(Object requester, String context);
}
public class UserActionMediator implements Mediator {
  private final ActionAppliedMessage actionAppliedMessage;
  private final SelectOptions selectOptions;
  private final WarningMessage warningMessage;

  public UserActionMediator(final ActionAppliedMessage actionAppliedMessage, final SelectOptions selectOptions, final WarningMessage warningMessage) {
    this.actionAppliedMessage = actionAppliedMessage;
    this.selectOptions = selectOptions;
    this.warningMessage = warningMessage;
    actionAppliedMessage.setMediator(this);
    selectOptions.setMediator(this);
    warningMessage.setMediator(this);
  }

  @Override
  public void sendInfo(final Object requester, final String context) {
    if (requester == actionAppliedMessage) {
      actionAppliedMessage.displayInfo();
      warningMessage.hideWarning();
      selectOptions.hideOptions();
    } else if (requester == selectOptions) {
      switch (context) {
        case "load":
          selectOptions.chooseLoad();
          actionAppliedMessage.displayInfo();
          break;
        case "restart":
          selectOptions.chooseRestart();
          warningMessage.showWarningMessage();
          break;
        case "save":
          selectOptions.chooseSave();
          actionAppliedMessage.displayInfo();
          break;
      }
    } else if (requester == warningMessage) {
      if (context.equals("hide")) {
        warningMessage.hideWarning();
      } else {
        warningMessage.showWarningMessage();
      }
    }
  }
}
public class MediatorUsage {
  public static void main(String[] args) {
    final ActionAppliedMessage actionAppliedMessage = new ActionAppliedMessage();
    final SelectOptions selectOptions = new SelectOptions();
    final WarningMessage warningMessage = new WarningMessage();

    final Mediator mediator = new UserActionMediator(actionAppliedMessage, selectOptions, warningMessage);

    selectOptions.sendRequest("load");
    selectOptions.sendRequest("save");
    selectOptions.sendRequest("restart");
    warningMessage.sendRequest("hide");
  }
}

/* Sample output
11:14:29.401 [main] INFO pl.sdacademy.mediator.SelectOptions - Loading previous data
11:14:29.403 [main] INFO pl.sdacademy.mediator.ActionAppliedMessage - Action was applied successfully
11:14:29.403 [main] INFO pl.sdacademy.mediator.SelectOptions - Status was saved
11:14:29.403 [main] INFO pl.sdacademy.mediator.ActionAppliedMessage - Action was applied successfully
11:14:29.403 [main] INFO pl.sdacademy.mediator.SelectOptions - Status is restarting
11:14:29.403 [main] WARN pl.sdacademy.mediator.WarningMessage - Are you sure?
11:14:29.403 [main] WARN pl.sdacademy.mediator.WarningMessage - Are you sure?
*/