Advertisment

Mediator Pattern

author-image
CIOL Bureau
Updated On
New Update

Girish Managoli, Avijeet

Dash
and Satyabrata Dash

Advertisment

Intent

Advertisment

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.

In 30 Seconds

Advertisment

The catch here is, "objects interacting through a central controller,

instead of interacting with each other directly".

Dividing the functionality and behavior into several classes enhances

reusability of the classes. This also helps in keeping the classes small,

modular and maintainable. However, as the number of classes increase, the

interactions and dependencies between the classes also increase. This makes the

system difficult to maintain and change. The idea here is to introduce a

"controller" class, through which all the other objects interact. All

classes depend only on the controller class; only the controller class knows

about all classes. The "controller" class is called Mediator.

Advertisment

Motivation

Advertisment

Concentrating the complexity in one class can reduce the overall complexity

of a system. The Mediator is the "know-all" class that decides how the

objects interact. The objects themselves are responsible for carrying out their

assigned tasks and know nothing about the other objects but the Mediator. This

enables the objects to be re-used in other systems independently of other

objects. Also, since the Mediator decides how the objects interact, replacing

the Mediator brings a different behavior in the system.

Structure

Advertisment

Click Here to

view picture

Advertisment

Examples

Example 1:

Let us say we are implementing a dialog like this:

(Actual dialog to be implemented in Java)

The text field "Spouse Name" is enabled if "Yes" radio

button is clicked.

Java Swing provides the GUI components that are designed to be reusable

components without any dependency between them. We have to implement a

"Mediator" class that controls how the components interact. Mediator

has to implement the ActionListener interface and gets notified when

"Yes" option is selected. The Mediator sends a signal to "Spouse

Name" text field to enable it. The class diagram and sequence diagram below

depict the object interactions.

Click Here to

view picture

Click Here to

view picture

Thoughts



The Mediator can share a common interface as shown in the structure above.

This enables replacing the ConcreteMediator class to allow a different behavior.

Also the Colleague classes can be effectively reused without having to be

rewritten for a new Mediator class.

There may be cases when a common Mediator interface is not necessary, when

the common interface can be avoided.

There is no necessity for the Colleague classes to share the same interface.

This only makes the pattern more restrictive. The Colleagues can conveniently be

unrelated set of classes.

In general, Mediator pattern is very effective and useful for building a low

coupling system by reducing the number of interactions between the objects, thus

enhancing the overall system testability, reusability and maintainability.



Sample Code

// Colleague.java



//


abstract class Colleague


{


private Mediator _aMediator;





public Colleague(Mediator m)


{


_aMediator = m;


}





public void changed()


{


_aMediator.colleagueChanged(this);


}





public Mediator getMediator()


{


return(_aMediator);


}





public abstract void Display();


}




















// Mediator.java



//

import java.io.*;






abstract class Mediator


{





public abstract void colleagueChanged(Colleague theChangedColleague);





public
static void
main(String

args<>)



{





ConcreteMediator aConcreteMediator = new ConcreteMediator();


aConcreteMediator.createConcreteMediator();





(aConcreteMediator.getOneColleage()).Display();


(aConcreteMediator.getNextColleague()).Display();





OneColleague newColleague = new OneColleague(aConcreteMediator,
"OneColleague");






aConcreteMediator.colleagueChanged( (OneColleague)newColleague
);






(aConcreteMediator.getOneColleage()).Display();


(aConcreteMediator.getNextColleague()).Display();





}





















}






// ConcreteMediator.java



//


class ConcreteMediator extends Mediator


{


private OneColleague _aOneColleague;



private NextColleague _aNextColleague;






public void colleagueChanged( Colleague theChangedColleague )


{





if ((( OneColleague)theChangedColleague).getSelection().equals(
_aOneColleague.getSelection() ) )



{


_aNextColleague.setText( _aOneColleague.getSelection() );


}





}





public void createConcreteMediator()


{





_aOneColleague = new OneColleague(this, "OneColleague");


_aNextColleague = new NextColleague(this, "NextColleague");





}



















// OneColleague.java



//


class OneColleague extends Colleague


{


private String _text;





public OneColleague(Mediator m, String t)


{


super( m );


_text = t;


}





public void setText(String text)


{


_text = text;


}





public String getSelection()


{


return(_text);


}





public void Display()


{


System.out.println("OneColleague = " + _text);


}


}
























// NextColleague.java



//


class NextColleague extends Colleague


{


private String _text;





public NextColleague(Mediator m, String t)


{


super( m );


_text = t;


}





public void setText(String text)


{


_text = text;


}





public String getSelection()


{


return( _text );


}





public void Display()


{


System.out.println("NextColleague = " + _text);


}


}
























Whenever the mediator's colleagueChanged() method is called (with a new

Colleague passed in as an argument), it compares the contents of the new

colleague with the contents of one of its colleagues (the OneColleague). If

there is a match it sets the contents of its other colleague (the NextColleague)

to match the first colleague (the OneColleague).

Complexities simplified

Omitting the Abstract Mediator Class

There’s no need to define an abstract Mediator class when colleagues work

with only one mediator.

Colleague-Mediator communication

Colleagues have to communicate with their mediator when an event of interest

occurs. One approach is to implement the mediator as an Observer pattern.

Colleague classes act as subjects, sending notifications to the mediator

whenever they change state.

The other approach is to define a specialized notification interface in

Mediator that lets colleagues be more direct in their communication.

Related Patterns

Facade and Mediator are similar; both result in a low coupling system. Facade

provides a simplified interface to a subsystem. The message flow in Facade is

unidirectional; clients make calls to the subsystem and not vice versa.

Mediator, in contrast, enables cooperative interaction between the objects and

message flow is multidirectional.

Colleagues can communicate with Mediator using Observer pattern.

tech-news