Mediator Pattern in Java
Chatroom Application using the Mediator Pattern
Here we will use the Mediator pattern in the context of a chatroom application.
First we will define an interface for our mediator
//Mediator interface
package com.java.behavioral.mediator;
public interface Mediator{
public void send(String message, Colleague colleague);
}
While we described the Colleague as an interface above, it is more useful to use an abstract class in this case:
//Colleague interface
package com.java.behavioral.mediator;
public abstract class Colleague {
private Mediator mediator;
public Colleague(Mediator m) {
mediator = m;
}
// send a message via the mediator
public void send(String message) {
mediator.send(message, this);
}
// get access to the mediator
public Mediator getMediator() {
return mediator;
}
public abstract void receive(String message);
}
Now let's create our concrete mediator implementation
package com.java.behavioral.mediator;
import java.util.*;
public class ApplicationMediator implements Mediator {
private ArrayList<Colleague> colleagues;
public ApplicationMediator() {
colleagues = new ArrayList<Colleague>();
}
public void addColleague(Colleague colleague) {
colleagues.add(colleague);
}
public void send(String message, Colleague originator) {
/* let all other screens know that this screen has changed */
for (Colleague colleague : colleagues) {
if (colleague != originator) {
colleague.receive(message);
}
}
}
}
Finally we will create one concrete colleage.
package com.java.behavioral.mediator;
public class ConcreteColleague extends Colleague {
public ConcreteColleague(Mediator m) {
super(m);
// TODO Auto-generated constructor stub
}
public void receive(String message) {
System.out.println("Colleague Received: " + message);
}
}
If we assume that we could have many different colleagues that react differently when a message is received, this pattern fits in well.
For example, we could have a mobileColleague that needs to display the message differently to the desktop colleague.
package com.java.behavioral.mediator;
public class MobileColleague extends Colleague {
public MobileColleague(Mediator m) {
super(m);
// TODO Auto-generated constructor stub
}
public void receive(String message) {
System.out.println("Mobile Received: " + message);
}
}
Here's a client that drives the entire application:
package com.java.behavioral.mediator;
public class Client {
public static void main(String[] args) {
ApplicationMediator mediator = new ApplicationMediator();
ConcreteColleague desktop = new ConcreteColleague(mediator);
MobileColleague mobile = new MobileColleague(mediator);
mediator.addColleague(desktop);
mediator.addColleague(mobile);
desktop.send("Hello World");
mobile.send("Hello");
}
}
Advantages of the Mediator Pattern
Mediators improve code organization in many ways: reducing subclassing, decoupling subsystems, and simplifying messaging systems and protocols.
Disadvantages of the Mediator Pattern
- Complexity can creep into a Mediator over time as you customize it for new applications. You have missed the point if you allow a Mediator to become too complex. Several Mediators tailored for specific applications can help. Be careful not to add back the complexity you are trying to eliminate.
- A mediator class can exceed its original intent if you are not careful. A good OO program is a network of cooperating agents.
Focus your mediators on doing one thing only.