Get up to 80 % extra points for free! More info:

Mediator

The Mediator design pattern introduces a mediator between direct communication of several objects. This reduces the coupling between these objects and regulates their responsibility. This is a very popular principle, also used by the Controller pattern from the GRASP pattern family, or the Indirection pattern also from GRASP.

Motivation

It's a bit of a paradox that we can often make our application simpler by adding an "artificial" class. If a group of objects interacts with each other directly, it generates unnecessary and complex coupling. If the object group only communicates with the mediator and the mediator communicates with the objects, the number of references will be reduced. Let's show how the situation could look like if some components were communicating with each other directly:

High coupling without applying the Mediator GOF design pattern - GOF - Behavioral Patterns

The number of references between the components is high, we violate low coupling and the components depend on each other. Now, let's try to introduce a mediator who will mediate whole communication:

Low coupling after applying the Mediator GOF design pattern - GOF - Behavioral Patterns

The mediator also reduces the need of the objects to know each other and simplifies the code. The object just has to be able to communicate with the mediator. It doesn't need to care about anything else. The communication mechanism between the objects then remains encapsulated in one place, in the mediator. Of course, objects can be easily changed without having to edit all other participants of the interaction.

In practice, the mediator is often used, for example, for communication between form elements. It helps us prevent the form components referencing each other. They will communicate with the mediator, a separate object modifying the form state according to the current actions.

Pattern

The Mediator pattern introduces several terms:

  • Mediator - Defines an abstract class for the mediator. There can be more concrete mediators.
  • Colleague - Defines an abstract class for colleagues, the objects in the interaction. Thanks to the abstract class, concrete colleagues can just simply inherit the reference to the mediator.
  • ConcreteColleague ... - Concrete objects implement any operations and have the reference to the mediator.
  • ConcreteMediator ... - Concrete mediators keep references to all the colleagues to mediate the communication.
The Mediator GOF design pattern – UML diagram - GOF - Behavioral Patterns

Example

A relatively classic example of using this pattern is to create a mediator for different logger types. The application then doesn't communicate with multiple loggers, but only with one mediator, which, according to methods and parameters, mediates the communication to the loggers. This use of the mediator is very similar to Facades, but with the difference that Facade often only delegates to the interface of an already existing implementation, while Mediator contains the logic, the code needed to mediate communication.

Such a mediator for logging could look like this:

public class LoggerMediator {
    private LoggingType loggingType;
    private FileLogger fileLogger = new FileLogger();

    public void setLoggingType(LoggingType loggingType) {
        this.loggingType = loggingType;
    }

    public void log(String message, Level level) {
        if (loggingType == LoggingType.Console) {
            if (level == Level.Error)
                System.err.println(message);
            else
                System.out.println(message);
        } else if (loggingType == LoggingType.File) {
            if (level == Level.Error)
                fileLogger.log(message, FileLogger.ERROR);
            else
                fileLogger.log(message, FileLogger.DEBUG);
        }
    }
}

Using some internal logic, the mediator delegates logging to different loggers. Let's show the difference against using a Facade to delegate to the loggers, which would only delegate the interface:

public class LoggerFacade {

    public void logInfo(final String message) {
        System.out.println(message);
    }

    public void logError(final String message) {
        System.err.println(message);
    }
}
  • Facade - Delegates functionality using a simple interface to a group of other objects

 

All articles in this section
GOF - Behavioral Patterns
Article has been written for you by David Capka Hartinger
Avatar
User rating:
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities