Шаблон проектирования посредника в Java
Шаблон проектирования «Посредник» — это один из шаблонов поведенческого проектирования, поэтому он имеет дело с поведением объектов. Шаблон проектирования посредника используется для обеспечения централизованной среды связи между различными объектами в системе.
Шаблон проектирования посредника
Обеспечивает слабую связь, инкапсулируя способ взаимодействия и связи друг с другом разрозненных наборов объектов. Позволяет действиям каждого набора объектов изменяться независимо друг от друга.
Шаблон проектирования посредника очень полезен в корпоративном приложении, где несколько объектов взаимодействуют друг с другом. Если объекты взаимодействуют друг с другом напрямую, компоненты системы тесно связаны друг с другом, что повышает стоимость сопровождения и упрощает расширение. Шаблон медиатора фокусируется на предоставлении посредника между объектами для связи и помощи в реализации потери связи между объектами. Авиадиспетчер — отличный пример модели посредника, когда диспетчерская аэропорта работает как посредник для связи между разными рейсами. Медиатор работает как маршрутизатор между объектами и может иметь собственную логику для обеспечения связи. Системные объекты, которые взаимодействуют друг с другом, называются коллегами. Обычно у нас есть интерфейс или абстрактный класс, который предоставляет контракт для связи, а затем у нас есть конкретная реализация посредников. В нашем примере мы попытаемся реализовать чат-приложение, в котором пользователи могут вести групповой чат. Каждый пользователь будет идентифицирован по имени и сможет отправлять и получать сообщения. Сообщение, отправленное любым пользователем, должно быть получено всеми остальными пользователями в группе.
Интерфейс шаблона посредника
Прежде всего, мы создадим интерфейс Медиатора, который будет определять контракт для конкретных посредников. 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<User> 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){
//message should not be received by the user sending it
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() использует посредника для отправки сообщения пользователям, и он понятия не имеет, как посредник будет обрабатывать его.
Пример шаблона посредника Код клиентской программы
Давайте протестируем наше чат-приложение с помощью простой программы, в которой мы создадим посредника и добавим пользователей в группу, а один из пользователей отправит сообщение. 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");
}
}
Обратите внимание, что клиентская программа очень проста и не знает, как обрабатывается сообщение и получает ли посредник пользователя или нет. Вывод примера программы шаблона медиатора:
Pankaj: Sending Message=Hi All
Lisa: Received Message:Hi All
Saurabh: Received Message:Hi All
David: Received Message:Hi All
Диаграмма класса шаблона посредника
Пример шаблона посредника в JDK
- Методы scheduleXXX() класса java.util.Timer
- Метод execute() Java Concurrency Executor.
- метод java.lang.reflect.Method invoke().
Важные моменты шаблона проектирования посредника
- Шаблон посредника полезен, когда логика связи между объектами сложна, у нас может быть центральная точка связи, которая заботится о логике связи.
- Служба сообщений Java (JMS) использует шаблон посредника вместе с шаблоном наблюдателя, чтобы приложения могли подписываться и публиковать данные в других приложениях.
- Мы не должны использовать шаблон посредника только для достижения потери связи, потому что, если количество посредников будет расти, их станет сложно поддерживать.
Это все, что касается шаблона проектирования посредника и его реализации в java.