Поиск по сайту:

Шаблон проектирования посредника в 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.