Mediator Pattern

Challenge

You are working on an Airline application managing flight validations. As you might know before taking off the flight, it goes through a series of checks ensuring the health of each component, the fuel level etc.

Our Flight class contains the following component classes

  • Engine
  • Wheels
  • Cockpit
  • Aviation

Each of the component class will be having a method named Start(). On invoking the method, it will ensure that the current state of component is valid through a method named IsReady(). If the IsReady() method returned true, the component class checks the other component IsReady() method. For example the Engine class ensures the Wheels and Aviation is in valid statue by using the IsReady() method of Wheel and Aviation respectively. The Cockpit in turn checks itself, Engine and the Aviation status. So there exists a coupling between the classes and code duplications. The scenario will become worse on introducing new components as classes.

MediatorPattern.gif

How to make the code better?

Definition

Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.

Implementation

We can improve the above situation by introducing the Mediator pattern. Through the introduction of Mediator the component classes won't talk to each other. All the components communicate to a new Mediator class. The advantages are:

  • Loosely coupled components
  • Centralized Management
  • More Flexibility in changing code

The new approach will look like below:

MediatorPattern1.gif

Here the component parts will communicate with the Mediator class for providing the ready signal to proceed with.

Classes

Following are the classes associated with the new implementation using Mediator Pattern.

public class FlightMediator
{
    private Engine _engine;
    private Aviation _aviation;
    private Wheels _wheels;
    private Cockpit _cockpit;
 
    public FlightMediator(Engine engine, Aviation aviation, Wheels wheels, Cockpit cockpit)
    {
        _engine = engine;
        _aviation = aviation;
        _wheels = wheels;
        _cockpit = cockpit;
    }
 
    public bool IsReady()
    {
        return _engine.IsReady() && _aviation.IsReady() && _wheels.IsReady() && _cockpit.IsReady();
    }
}
 
public class Engine
{
    public void Start()
    {
    } 
    public bool IsReady()
    {
        return true;
    }
}
 
public class Aviation
{
    private int _FuelLevel = 1000;
 
    public bool IsReady()
    {
        return _FuelLevel > 5000;
// Returns false as not enough fuel
    }

public class Wheels
{
    public bool IsReady()
    {
        return true;
    }
}
 
public class Cockpit
{
    public bool IsReady()
    {
        return true;
    }
}

Please note that the Aviation class returns false for the IsReady() method. The FlightMediator constructor takes all the component classes as inputs. The IsReady() method checks all the associated component's IsReady() method to ensure validations are right.

On running the Windows Forms application, you can see the following screen.

MediatorPattern2.gif

Clicking on the FlightMediator button you can see the color changing to red as the status returned is false.

MediatorPattern3.gif

Summary

In this article we have explore the Mediator pattern. The example is provided in a simple problem scenario, but the real world problems will be much complicated. For example a Wizard Page Framework where each page has to think about the previous and next pages could be made better using the Mediator pattern. The associated source code is attached with the article.