Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

title Mediator
category Behavioral
language en
tags
Gang Of Four
Decoupling

Intent

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.

Explanation

Real-world example

Rogue, wizard, hobbit, and hunter have decided to join their forces and travel in the same party. To avoid coupling each member with each other, they use the party interface to communicate with each other.

In plain words

Mediator decouples a set of classes by forcing their communications flow through a mediating object.

Wikipedia says

In software engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior. In object-oriented programming, programs often consist of many classes. Business logic and computation are distributed among these classes. However, as more classes are added to a program, especially during maintenance and/or refactoring, the problem of communication between these classes may become more complex. This makes the program harder to read and maintain. Furthermore, it can become difficult to change the program, since any change may affect code in several other classes. With the mediator pattern, communication between objects is encapsulated within a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby reducing coupling.

Programmatic Example

In this example, the mediator encapsulates how a set of objects interact. Instead of referring to each other directly they use the mediator interface.

The party members Rogue, Wizard, Hobbit, and Hunter all inherit from the PartyMemberBase implementing the PartyMember interface.

public interface PartyMember { void joinedParty(Party party); void partyAction(Action action); void act(Action action); } @Slf4j public abstract class PartyMemberBase implements PartyMember { protected Party party; @Override public void joinedParty(Party party) { LOGGER.info("{} joins the party", this); this.party = party; } @Override public void partyAction(Action action) { LOGGER.info("{} {}", this, action.getDescription()); } @Override public void act(Action action) { if (party != null) { LOGGER.info("{} {}", this, action); party.act(this, action); } } @Override public abstract String toString(); } public class Rogue extends PartyMemberBase { @Override public String toString() { return "Rogue"; } } // Wizard, Hobbit, and Hunter are implemented similarly

Our mediator system consists of Party interface and its implementation.

public interface Party { void addMember(PartyMember member); void act(PartyMember actor, Action action); } public class PartyImpl implements Party { private final List<PartyMember> members; public PartyImpl() { members = new ArrayList<>(); } @Override public void act(PartyMember actor, Action action) { for (var member : members) { if (!member.equals(actor)) { member.partyAction(action); } } } @Override public void addMember(PartyMember member) { members.add(member); member.joinedParty(this); } }

Here's a demo showing the mediator pattern in action.

 // create party and members Party party = new PartyImpl(); var hobbit = new Hobbit(); var wizard = new Wizard(); var rogue = new Rogue(); var hunter = new Hunter(); // add party members party.addMember(hobbit); party.addMember(wizard); party.addMember(rogue); party.addMember(hunter); // perform actions -> the other party members // are notified by the party hobbit.act(Action.ENEMY); wizard.act(Action.TALE); rogue.act(Action.GOLD); hunter.act(Action.HUNT);

Here's the console output from running the example.

Hobbit joins the party Wizard joins the party Rogue joins the party Hunter joins the party Hobbit spotted enemies Wizard runs for cover Rogue runs for cover Hunter runs for cover Wizard tells a tale Hobbit comes to listen Rogue comes to listen Hunter comes to listen Rogue found gold Hobbit takes his share of the gold Wizard takes his share of the gold Hunter takes his share of the gold Hunter hunted a rabbit Hobbit arrives for dinner Wizard arrives for dinner Rogue arrives for dinner 

Class diagram

alt text

Applicability

Use the Mediator pattern when

  • A set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructured and difficult to understand
  • Reusing an object is difficult because it refers to and communicates with many other objects
  • A behavior that's distributed between several classes should be customizable without a lot of subclassing

Known uses

Credits