Z życia wzięte …
„… centralny magazyn firmy, przychodzą do niego materiały, narzędzia, półfabrykaty. Jako jedyny zna adresy poszczególnych oddziałów i osoby odpowiedzialne za przepływ materiałów w danym oddziale. Jego sprawne działanie ma wpływ na bezproblemowe wytwarzanie produktów firmy. Po co taki centralny magazyn, nie lepiej żeby poszczególne działy kontaktowały się ze sobą? A jednak nie, taki centralny dział który jako jedyny wie o innych, zaprowadza porządek w chaosie. …”
Mediator – czynnościowy wzorzec projektowy, który:
- Jako jedyny zna większość współpracujących ze sobą obiektów
- Zapewnia zmniejszenie ilości powiązań pomiędzy klasami
- Daje jednolity interfejs do przesyłania komunikatów pomiędzy klasami
Mediator jest podobny w działaniu do wzorca obserwatora, lecz występują różnice: obserwator zna wszystkie obiekty do których jest wysyłany komunikat, mediator – hermetyzuje to połączenia, obiekt nadający zna tylko mediatora, żadnego innego obiektu
Zalety:
- Luźna zależność pomiędzy obiektami w systemie – nadawca komunikatu -> mediator -> odbiorca lub odbiorcy komunikatów
- Relacja pomiędzy tymi obiektami jest dynamiczna, jest możliwe dodanie nowych opcji w trakcie działania systemu
- Możliwość ograniczenia korzystania z poszczególnych elementów systemu, wystarczy odłączyć danego odbiorcę komunikatów lub nadawcę komunikatów
Wady:
- Możliwość zapętlenia się aplikacji w przypadku gdy jeden obiekt jest równocześnie odbiorcą i nadawcą komunikatów. Na skutek odebrania komunikatu obiekt zmienia swój stan i nadaje nowy komunikat. W tym przypadku grozi nam zapętlenie się kolejki komunikatów.
Przykładowa implementacja (Java):
package pl.shad.net.blog; import java.util.ArrayList; /** * Definicja interfejsu mediatora */ interface Mediator{ void sendMessage(String message); } /** * Klasa implementująca interfejs mediatora, * jako jednyna zna wszystkie obiekty robocze */ class MediatorHub implements Mediator{ private ArrayList< JobWorker > jobWorkers = new ArrayList< JobWorker >(); /** * Dodanie obiektu do obsługi komunikatów * @param jobWorker */ public void addJobWorker(JobWorker jobWorker){ jobWorkers.add(jobWorker); } /** * Usunięcie obiektu z obsługi komunikatów * @param jobWorker */ public void removeJobWorker(JobWorker jobWorker){ jobWorkers.remove(jobWorker); } /** * Wysłanie komunikatu do współpracujących obiektów * @param message */ @Override public void sendMessage(String message){ for (JobWorker jobWorker : jobWorkers){ jobWorker.receiveMessage(message); } } } /** * Klasa definująca obiekt wysyłający komunikaty do mediatora * i odbirający komunikaty od mediatora */ class JobWorker{ private String name; private Mediator mediator; public JobWorker(String name, Mediator mediator){ this.name = name; this.mediator = mediator; } /** * Wysłanie komunikatu */ public void sendMessage(){ this.mediator.sendMessage(name + " send msg"); } /** * Odebranie komunikatu * @param message */ public void receiveMessage(String message){ System.out.println("Message -> msg: '" + message + "' to: " + name); } } /** * Uruchomieniowa klasa testująca */ public class DesignPatternsMediator{ public static void main(String[] args){ // // Utworzenie obiektów oraz stworzenie dynamicznych powiązań // MediatorHub mediatorHub = new MediatorHub(); JobWorker job1 = new JobWorker("Job1", mediatorHub); JobWorker job2 = new JobWorker("Job2", mediatorHub); JobWorker job3 = new JobWorker("Job3", mediatorHub); JobWorker job4 = new JobWorker("Job4", mediatorHub); mediatorHub.addJobWorker(job1); mediatorHub.addJobWorker(job2); mediatorHub.addJobWorker(job3); mediatorHub.addJobWorker(job4); // // Wysłanie komunikatu od obiektu1 do wszytkch obiektów roboczych // job1.sendMessage(); // // Wysłanie komunikatu od obiektu2 do wszytkch obiektów roboczych // poza obiektem2 // mediatorHub.removeJobWorker(job2); job2.sendMessage(); } } |
1 Pingback