В этом уроке мы узнаем о поведенческом паттерне, который способствует слабой связи между несколькими объектами, связывающимися друг с другом. Идея шаблона проектирования Mediator состоит в том, чтобы иметь центральный объект, который инкапсулирует взаимодействие набора объектов.
В паттерне медиатора мы извлекаем все отношения между различными классами в отдельном классе, известном как медиатор. Это позволяет нам вносить изменения в один компонент, не влияя на всю систему.
Итак, у нас есть более слабосвязанная система, которую проще расширять и обслуживать.
Представление UML:
Мы можем представить шаблон посредника с помощью следующей диаграммы UML:

Здесь мы имеем:
- Посредник: интерфейс или абстрактный класс, определяющий договор для общения между коллегами
- ConcreteMediator: класс, реализующий посреднический контракт; он знает обо всех коллегах и их взаимосвязях. Любое общение между коллегами происходит только через посредника
- Коллега: интерфейс или абстрактный класс, представляющий компоненты нашей системы
- ConcreteColleague: классы, которые реализуют интерфейс Colleague и готовы взаимодействовать друг с другом
Реализация шаблона посредника:
Давайте возьмем пример системы управления воздушным движением.
Каждый рейс должен знать о наличии ВПП для его посадки. Если мы позволим интер-связи между самолетами, чтобы они нашли доступную взлетно-посадочную полосу, это приведет к хаосу. Скорее, это хорошая идея иметь диспетчерскую, которая отслеживает все доступные взлетно-посадочные полосы и назначает их самолету.
Давайте начнем с определения AircraftMediator и AircraftTrafficControlRoom :
|
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
30
31
32
33
34
35
36
|
public interface AircraftMediator { public void registerRunway(Runway runway); public String allotRunwayTo(Aircraft aircraft); public void releaseRunwayOccupiedBy(Aircraft aircraft); } public class AicraftTrafficControlRoom implements AircraftMediator { private LinkedList<Runway> availableRunways = new LinkedList<>(); private Map<Aircraft, Runway> aircraftRunwayMap = new HashMap<>(); @Override public void registerRunway(Runway runway) { this.availableRunways.add(runway); } @Override public String allotRunwayTo(Aircraft aircraft) { Runway nextAvailbleRunway = null; if(!this.availableRunways.isEmpty()) { nextAvailbleRunway = this.availableRunways.removeFirst(); this.aircraftRunwayMap.put(aircraft, runway); } return nextAvailbleRunway == null ? null : nextAvailbleRunway.getName(); } @Override public void releaseRunwayOccupiedBy(Aircraft aircraft) { if(this.aircraftRunwayMap.containsKey(aircraft)) { Runway runway = this.aircraftRunwayMap.remove(aircraft); this.availableRunways.add(runway); } }} |
Зал управления воздушным движением выступает в качестве посредника и отслеживает все доступные взлетно-посадочные полосы. Он отвечает за выделение и выпуск взлетно-посадочных полос.
Определение коллег:
Теперь давайте определимся с нашими самолетами , экземплярами которых станут коллеги:
|
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
30
31
32
|
public interface AircraftColleague { void startLanding(); void finishLanding();} public class Aircraft implements AircraftColleague { private AircraftMediator mediator; private String flightName; public Aircraft(AircraftMediator mediator, String flightName) { this.mediator = mediator; this.flightName = flightName; } @Override public void startLanding() { String runway = this.mediator.allotRunwayTo(this); if(runway == null) { //informing passengers System.out.println("Due to traffic, there's a delay in landing of " + this.flightName ); } else { System.out.println("Currently landing " + this.flightName + " on " + runway); } } @Override public void finishLanding() { System.out.println(this.flightName + "landed successfully"); this.mediator.releaseRunwayOccupiedBy(this); }} |
Тестирование нашей реализации:
Давайте посмотрим, как это работает вместе:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
// In our main methodRunway runwayA = new Runway("Runway A"); AircraftMediator mediator = new AircraftTrafficControlRoom();mediator.registerRunway(runwayA); AircraftColleague wrightFlight = new Aircraft(mediator, "Wright Flight"); AircraftColleague airbusA380 = new Aircraft(mediator, "Airbus A380"); wrightFlight.startLanding(); airbusA380.startLanding();wrightFlight.finishLanding(); |
При выполнении приведенного выше кода у нас будет следующий вывод:
|
1
2
3
|
Currently landing Wright Flight on Runway ADue to traffic, there's a delay in landing of Airbus A380Wright Flight landed successfully |
Если мы снова предпримем попытку приземления аэробуса, мы сможем продолжить его, поскольку взлетно-посадочная полоса теперь доступна.
Вывод:
В этом уроке мы узнали, как реализовать шаблон посредника. Мы будем использовать шаблон-посредник, когда у нас есть система, в которой несколько объектов взаимодействуют друг с другом. Эта схема способствует слабому сцеплению и тем самым делает систему более гибкой.
Распространенным применением этого шаблона является система чата или обмена сообщениями. Кроме того, метод execute () Java Concurrency Executor использует этот шаблон.
|
Опубликовано на Java Code Geeks с разрешения Шубхры Шриваставы, партнера нашей программы JCG . Посмотрите оригинальную статью здесь: Шаблон дизайна посредника в Java Мнения, высказанные участниками Java Code Geeks, являются их собственными. |