Уявіть, що ви розробляєте систему для управління різними домашніми приладами, такими як вентилятор, світло і кондиціонер. Патерн проектування Mediator допомагає централізувати взаємодії між об’єктами, дозволяючи їм не взаємодіяти безпосередньо один з одним. Замість того, щоб кнопка чи вентилятор безпосередньо зверталися до інших об’єктів, між ними працює проміжний об’єкт, медіатор, який і контролює всю комунікацію.
У нашому прикладі є хлопець на ім'я Рей, який натискає кнопку, що на стіні. Кнопка не керує вентилятором напряму, а лише передає сигнал медіатору, який вирішує, чи включити вентилятор чи вимкнути його. Така взаємодія значно спрощує код, робить його більш гнучким і дозволяє зменшити зв'язування між компонентами.
Розглянемо це в контексті патерну проектування Mediator, описаного «Групою чотирьох» (GoF). Патерн передбачає визначення об'єкта, який інкапсулює взаємодії між наборами об’єктів. Це знижує зв'язування між компонентами, оскільки об’єкти не посилаються один на одного безпосередньо, а взаємодіють через медіатора.
Ключовими компонентами є:
1. Медіатор — об’єкт, який інкапсулює взаємодії між компонентами.
2. Колеги — компоненти, які спілкуються між собою через медіатора.
Переваги:
- Слабке зв'язування: Компоненти взаємодіють через медіатора, що знижує залежності та полегшує підтримку системи.
- Краща читабельність коду: Логіка взаємодії централізована в медіаторі, що робить код більш зрозумілим.
- Легше підтримувати: Зміни в поведінці об’єктів можна реалізувати, змінюючи лише медіатор.
- Спрощення комунікації: Медіатор обробляє всі взаємодії, зменшуючи надлишковий код.
Переходимо до реалізації цього патерну в коді:
-
Інтерфейс медіатора:
java
package com.lpj.mediator;public interface Mediator {
void press();
} -
Конкретний медіатор:
java
package com.ljp.colleagues;import mediator.Mediator;
public class Button {
private Mediator mediator;public void setMediator(Mediator mediator) { this.mediator = mediator; } public void press() { System.out.println("Рей натиснув кнопку."); mediator.press(); }
}
-
Пристрій і конкретна реалізація (Колега 1):
java
package com.ljp.colleagues;public interface Appliance {
public void turnOn();
public void turnOff();
public boolean isOn();
}public class Fan implements Appliance {
private boolean isOn = false;@Override public void turnOn() { isOn = true; System.out.println("Вентилятор увімкнено"); } @Override public void turnOff() { isOn = false; System.out.println("Вентилятор вимкнено"); } @Override public boolean isOn() { return isOn; }
}
-
Колега 2:
java
package com.ljp.colleagues;import com.ljp.mediators.Mediator;
public class Button {
private Mediator mediator;public void setMediator(Mediator mediator) { this.mediator = mediator; } public void press() { System.out.println("Рей натиснув кнопку."); mediator.press(); }
}
-
Основний клас:
java
import com.ljp.colleagues.Button;
import com.ljp.colleagues.Fan;
import com.ljp.mediator.FanMediator;
import com.ljp.mediator.Mediator;public class MediatorDemoMain {
public static void main(String[] args) {
Button button = new Button();
Fan fan = new Fan();createMediator(button, fan); button.press(); // Рей натискає один раз button.press(); // Рей натискає ще раз } private static FanMediator createMediator(Button button, Fan fan) { return new FanMediator(button, fan); }
}
Повний код для цього проєкту можна знайти в репозиторії на GitHub: GitHub Repository Link
Висновок:
Патерн Mediator дозволяє спростити взаємодії між об’єктами, центрально організуючи їх комунікацію. Це дозволяє знижувати залежності, покращує підтримку коду та забезпечує гнучкість у розвитку проектів.
Додаткові примітки:
В програмуванні часто починається з простих рішень, але з часом система розростається, і підтримка її без правильної організації стає важкою. Патерн Mediator допомагає зберігати чистоту коду навіть при масштабуванні проектів. Наприклад, за допомогою однієї кнопки можна керувати світлом, кондиціонером і вентилятором через медіатора, просто додаючи нові пристрої.
-
Медіатор:
java
package com.ljp.mediators;public interface Mediator {
void press();
} -
Розумний медіатор:
java
package com.ljp.mediators;import com.ljp.colleagues.Appliance;
import com.ljp.colleagues.SmartButton;
import com.ljp.colleagues.Fan;import java.util.List;
public class SmartMediator implements Mediator {
private List<Appliance> appliances; public SmartMediator(List<Appliance> appliances) { this.appliances = appliances; } @Override public void press() { // Сповіщаємо всі пристрої for (Appliance appliance : appliances) { // Перевіряємо стан всіх пристроїв і перемикаємо if (appliance.isOn()) { appliance.turnOff(); } else { appliance.turnOn(); } } }
}
Тепер, з допомогою цього патерну, система може масштабуватися, керуючи різними пристроями через одного медіатора, що робить код чистим і легким для підтримки.
Перекладено з: Mediator design pattern — Made Simple