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.
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:
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.
Clicking on the FlightMediator button you can see the color changing to red as
the status returned is false.
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.