Посреднический паттерн — это один из паттернов поведенческого проектирования , поэтому он имеет дело с поведением объектов. Шаблон проектирования посредника используется для обеспечения централизованной среды связи между различными объектами в системе. Согласно GoF, намерение посредника:
Позволяет слабой связи, инкапсулируя способ взаимодействия и связи разнородных наборов объектов. Позволяет действиям каждого объекта изменяться независимо друг от друга.
Шаблон проектирования посредника очень полезен в корпоративном приложении, где несколько объектов взаимодействуют друг с другом. Если объекты взаимодействуют друг с другом напрямую, компоненты системы тесно связаны друг с другом, что повышает стоимость обслуживания и не позволяет легко расширяться. Шаблон посредника фокусируется на предоставлении посредника между объектами для связи и помощи в реализации потери связи между объектами.
Авиадиспетчер является отличным примером посреднической схемы, когда диспетчерский пункт аэропорта выступает в качестве посредника для связи между различными рейсами. Посредник работает как маршрутизатор между объектами и может иметь собственную логику для обеспечения связи.
Системные объекты, которые общаются друг с другом, называются коллегами. Обычно у нас есть интерфейс или абстрактный класс, который предоставляет контракт для связи, а затем у нас есть конкретная реализация посредников.
В нашем примере мы попытаемся реализовать приложение для чата, где пользователи могут вести групповой чат. Каждый пользователь будет идентифицирован по имени, и они могут отправлять и получать сообщения. Сообщение, отправленное любым пользователем, должно быть получено всеми другими пользователями в группе.
Интерфейс посредника
Прежде всего, мы создадим интерфейс посредника, который будет определять контракт для конкретных посредников.
|
1
2
3
4
5
6
7
8
|
package com.journaldev.design.mediator;public interface ChatMediator { public void sendMessage(String msg, User user); void addUser(User user);} |
Интерфейс коллеги
Пользователи могут отправлять и получать сообщения, поэтому мы можем иметь пользовательский интерфейс или абстрактный класс. Я создаю пользователя как абстрактный класс, как показано ниже.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
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);} |
Обратите внимание, что у пользователя есть ссылка на объект-посредник, он необходим для связи между разными пользователями.
Конкретный Медиатор
Теперь мы создадим конкретный класс-посредник, он будет иметь список пользователей в группе и предоставит логику для общения между пользователями.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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); } } }} |
Конкретный Коллега
Теперь мы можем создавать конкретные пользовательские классы для использования клиентской системой.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
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 Client
Давайте протестируем это наше приложение для чата с помощью простой программы, в которой мы создадим посредника и добавим пользователей в группу, а один из пользователей отправит сообщение.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
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"); }} |
Обратите внимание, что клиентская программа очень проста, и она не знает, как обрабатывается сообщение и получает ли посредник пользователя или нет.
Вывод вышеуказанной программы:
|
1
2
3
4
|
Pankaj: Sending Message=Hi AllLisa: Received Message:Hi AllSaurabh: Received Message:Hi AllDavid: Received Message:Hi All |
Диаграмма классов паттернов-посредников
Образец посредника в JDK
- java.util.Timer класс scheduleXXX () методы
- Java Concurrency Executor execute () метод.
- java.lang.reflect.Method метод invoke ().
Важные точки
- Шаблон посредника полезен, когда логика коммуникации между объектами сложна, у нас может быть центральная точка коммуникации, которая заботится о логике коммуникации.
- Служба сообщений Java (JMS) использует шаблон Mediator вместе с шаблоном Observer, чтобы позволить приложениям подписываться и публиковать данные в других приложениях.
- Мы не должны использовать модель посредников только для того, чтобы добиться потерянной связи, потому что, если число посредников будет расти, их будет сложно поддерживать.
