Mediator znajduje zastosowanie w sytuacji, gdy wiele obiektów o wspólnym interfejsie musi komunikować się ze sobą w celu wykonania określonego zadania. Najprostszym, lecz trochę naiwnym rozwiązaniem jest powiązanie wszystkich obiektów ze sobą w topologii grafu pełnego. Takie rozwiązanie jest jednak słabo skalowalne: dołączenie kolejnego obiektu powoduje konieczność powiadomienia o zmianie wszystkich pozostałych, aby potrafili skomunikować się z nowym uczestnikiem interakcji. Ponadto powoduje, że mechanizm komunikacji jest rozproszony, co utrudnia jego modyfikację i dalszy rozwój.
Wzorzec Mediator proponuje topologię gwiazdy, w której centrum znajduje się właśnie obiekt Mediator. Posiada on referencje do pozostałych obiektów (Colleague) i zna ich zakres odpowiedzialności. Komunikacja pomiędzy obiektami Colleague wymaga pośrednictwa Mediatora, który potrafi przekazać komunikat do właściwego odbiorcy.
Mediator
package pl.roboczenotatki.designpatterns.mediator; public interface Mediator { public void notifyAll(String message,Colleague authorColleague); }
Colleague
package pl.roboczenotatki.designpatterns.mediator; public interface Colleague { public void send(String message); public void receive(String message); public String getName(); }
ConcreteColleague
package pl.roboczenotatki.designpatterns.mediator; public class ConcreteColleague implements Colleague{ private Mediator mediator; private String name; public ConcreteColleague(Mediator mediator, String name) { super(); this.mediator = mediator; this.name = name; } @Override public void receive(String message) { System.out.println("[Colleague] '"+getName()+"' received message: " + message); } public Mediator getMediator() { return this.mediator; } @Override public void send(String message) { getMediator().notifyAll(message, this); } public String getName() { return this.name; } }
ConcreteMediator
package pl.roboczenotatki.designpatterns.mediator; import java.util.ArrayList; import java.util.List; public class ConcreteMediator implements Mediator { private List colleagues; public List getColleagues() { if(colleagues == null){ colleagues = new ArrayList(); } return colleagues; } public void addColleague(Colleague colleague){ getColleagues().add(colleague); } public void addColleagues(List colleagues){ getColleagues().addAll(colleagues); } @Override public void notifyAll(String m, Colleague authorColleague) { System.out.println("[Mediator] Message from author '" + authorColleague.getName() + "' : " + m); for (Colleague c : getColleagues()) { c.receive(m); } } }
package pl.roboczenotatki.designpatterns.mediator; import java.util.Arrays; public class App { public static void main( String[] args ) { System.out.println( "Design pattern: mediator" ); ConcreteMediator mediator = new ConcreteMediator(); Colleague col1 = new ConcreteColleague(mediator, "1"); Colleague col2 = new ConcreteColleague(mediator, "2"); Colleague col3 = new ConcreteColleague(mediator, "3"); Colleague col4 = new ConcreteColleague(mediator, "4"); //dodajemy obslugiwanych kolegow mediator.addColleagues(Arrays.asList(col1,col2,col3,col4)); //col1 powiadamia pozostalych - rozsyla poprzez mediatora col1.send("hello from 1"); } }
Wynik wykonania:
Design pattern: mediator [Mediator] Message from author '1' : hello from 1 [Colleague] '1' received message: hello from 1 [Colleague] '2' received message: hello from 1 [Colleague] '3' received message: hello from 1 [Colleague] '4' received message: hello from 1