Паттерн проектирования “Посредник” является одним из поведенческих паттернов проектирования, поэтому он занимается поведением объектов. Паттерн проектирования “Посредник” используется для обеспечения централизованной среды обмена данными между различными объектами в системе.
Паттерн проектирования “Посредник”
Согласно GoF, намерение паттерна посредника заключается в следующем:
Позволяет слабую связанность, инкапсулируя способ взаимодействия и коммуникации различных наборов объектов друг с другом. Позволяет действиям каждого набора объектов варьироваться независимо друг от друга.
Паттерн проектирования “Mediator” очень полезен в корпоративных приложениях, где множество объектов взаимодействуют друг с другом. Если объекты взаимодействуют напрямую, компоненты системы тесно связаны друг с другом, что приводит к более высоким затратам на поддержку и сложности расширения. Паттерн “Mediator” сосредотачивается на предоставлении посредника между объектами для обмена информацией и помощи в реализации слабой связи между ними. Хорошим примером паттерна “Mediator” является диспетчер воздушного движения, где комната управления аэропорта действует как посредник для общения между различными рейсами. Посредник действует как маршрутизатор между объектами, и он может иметь свою собственную логику для обеспечения способа общения. Объекты системы, взаимодействующие друг с другом, называются коллегами. Обычно у нас есть интерфейс или абстрактный класс, который предоставляет контракт для общения, а затем у нас есть конкретная реализация посредников. В нашем примере мы попробуем реализовать приложение для чата, где пользователи могут вести групповой чат. Каждого пользователя можно идентифицировать по его имени, и они могут отправлять и получать сообщения. Сообщение, отправленное любым пользователем, должно быть получено всеми остальными пользователями в группе.
Интерфейс паттерна “Mediator”
Прежде всего создадим интерфейс посредника, который будет определять контракт для конкретных посредников. ChatMediator.java
package com.journaldev.design.mediator;
public interface ChatMediator {
public void sendMessage(String msg, User user);
void addUser(User user);
}
Интерфейс коллег по шаблону посредника
Пользователи могут отправлять и получать сообщения, поэтому у нас может быть интерфейс пользователя или абстрактный класс. Я создаю пользователя как абстрактный класс, как показано ниже. User.java
package com.journaldev.design.mediator;
public abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator med, String name){
this.mediator=med;
this.name=name;
}
public abstract void send(String msg);
public abstract void receive(String msg);
}
Обратите внимание, что у пользователя есть ссылка на объект посредника, это необходимо для общения между разными пользователями.
Конкретный посредник
Теперь мы создадим конкретный класс посредника, в котором будет список пользователей в группе и предоставлена логика для общения между пользователями. ChatMediatorImpl.java
package com.journaldev.design.mediator;
import java.util.ArrayList;
import java.util.List;
public class ChatMediatorImpl implements ChatMediator {
private List users;
public ChatMediatorImpl(){
this.users=new ArrayList<>();
}
@Override
public void addUser(User user){
this.users.add(user);
}
@Override
public void sendMessage(String msg, User user) {
for(User u : this.users){
// сообщение не должно быть получено отправляющим пользователем
if(u != user){
u.receive(msg);
}
}
}
}
Конкретный коллега шаблона проектирования посредника
Теперь мы можем создать конкретные классы пользователей для использования клиентской системой. UserImpl.java
package com.journaldev.design.mediator;
public class UserImpl extends User {
public UserImpl(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg){
System.out.println(this.name+": Sending Message="+msg);
mediator.sendMessage(msg, this);
}
@Override
public void receive(String msg) {
System.out.println(this.name+": Received Message:"+msg);
}
}
Обратите внимание, что метод send() использует посредника для отправки сообщения пользователям, и он не знает, как это будет обработано посредником.
Пример клиентского кода для шаблона “Mediator Pattern”
Давайте протестируем наше чат-приложение с помощью простой программы, в которой мы создадим посредника, добавим пользователей в группу, и один из пользователей отправит сообщение. ChatClient.java
package com.journaldev.design.mediator;
public class ChatClient {
public static void main(String[] args) {
ChatMediator mediator = new ChatMediatorImpl();
User user1 = new UserImpl(mediator, "Pankaj");
User user2 = new UserImpl(mediator, "Lisa");
User user3 = new UserImpl(mediator, "Saurabh");
User user4 = new UserImpl(mediator, "David");
mediator.addUser(user1);
mediator.addUser(user2);
mediator.addUser(user3);
mediator.addUser(user4);
user1.send("Hi All");
}
}
Обратите внимание, что клиентская программа очень проста и не имеет представления о том, как обрабатывается сообщение и получает ли посредник пользователя или нет. Результат работы программы с примером шаблона “Mediator Pattern”:
Pankaj: Sending Message=Hi All
Lisa: Received Message:Hi All
Saurabh: Received Message:Hi All
David: Received Message:Hi All
Диаграмма классов для шаблона “Mediator Pattern”
Пример шаблона “Mediator Pattern” в JDK
- Класс java.util.Timer с методами scheduleXXX()
- Интерфейс Java Concurrency Executor с методом execute().
- Метод invoke() класса java.lang.reflect.Method.
Важные моменты паттерна проектирования “Mediator”
- Паттерн “Mediator” полезен, когда логика взаимодействия между объектами сложна, и у нас может быть центральная точка общения, которая управляет логикой взаимодействия.
- Служба сообщений Java (JMS) использует паттерн “Mediator” вместе с паттерном “Observer” для возможности приложения подписываться и публиковать данные для других приложений.
- Не следует использовать паттерн “Mediator” просто для достижения слабой связности, потому что при увеличении числа посредников их поддержка может стать сложной.
Это все, что касается паттерна проектирования “Mediator” и его реализации в Java.
Source:
https://www.digitalocean.com/community/tutorials/mediator-design-pattern-java