Посередник (шаблон проектування)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Посередник (англ. Mediator) - шаблон проектування, відноситься до класу шаблонів поведінки.

Зміст

Призначення [ред.]

Визначає об'єкт, що інкапсулює спосіб взаємодії множини об'єктів. Посередник забезпечує слабку зв'язаність системи, звільняючи об'єкти від необхідності явно посилатися один на одного, і дозволяючи тим самим незалежно змінювати взаємодії між ними.

Застосовність [ред.]

Слід використовувати шаблон Посередник у випадках, коли:

  • існують об'єкти, зв'язки між котрими досить складні та чітко задані. Отримані при цьому залежності не структуровані та важкі для розуміння;
  • не можна повторно використовувати об'єкт, оскільки він обмінюється інформацією з багатьма іншими об'єктами;
  • поведінка, розподілена між кількома класами, повинна піддаватися налагодженню без створювання множини підкласів.

Структура [ред.]

UML діаграма, що описує структуру шаблону проектування Посередник
  • Mediator – посередник:
    • визначає інтерфейс для обміну інформацією з об'єктами Colleague;
  • ConcreteMediator – конкретний посередник:
    • реалізує кооперативну поведінку, координуючи дії об'єктів Colleague;
    • володіє інформацією про колег, та підраховує їх;
  • Класи Colleague – колеги:
    • кожному класу Colleague відомо про свій об'єкт Mediator;
    • усі колеги обмінюються інформацією виключно через посередника, інакше за його відсутності їм довелося б спілкуватися між собою напряму.

Відносини [ред.]

Колеги посилають запити посередникові та отримують запити від нього. Посередник реалізує кооперативну поведінку шляхом переадресації кожного запиту відповідному колезі (або декільком з них).

Приклади [ред.]

Java [ред.]

package example.pattern.mediator;
import java.util.Random;
 
// Mediator
public class TankCommander {
        private TankDriver driver; 
        private TankGunner gunner;
        private TankLoader loader;
 
        public void setDriver(TankDriver driver) {
                this.driver = driver;
        }
 
        public void setGunner(TankGunner gunner) {
                this.gunner = gunner;
        }
 
        public void setLoader(TankLoader loader) {
                this.loader = loader;
        }
 
        public void targetDetected(String target) {
                System.out.println("Commander: new target detected!");
                gunner.setWeapon(
                                loader.prepareWeapon(target));
                driver.halt();
                gunner.fire(target);
        }
 
        public void noTarget() {
                System.out.println("Commander: no target.");
                gunner.stopFire();
                driver.move();
        }
 
}
 
// Colleague
public class TankDriver {
        private TankCommander commander;
        private int fuel = 4;
 
        public TankDriver(TankCommander commander) {
                this.commander = commander;
                this.commander.setDriver(this);
        }
 
        public void move() {
                if (fuel <= 0 ) {
                        System.out.println("Driver: no fuel!");
                        return;
                }
                System.out.println("Driver: tank is moving!");
                fuel--;
                // looking for a new target
                if ((new Random()).nextInt(2) == 0) {
                        commander.targetDetected("armored");
                } else {
                        commander.targetDetected("infantry");
                }
        }
 
        public void halt() {
                System.out.println("Driver: tank has halted!");
        }
}
 
// Colleague
public class TankGunner {
        private TankCommander commander;
        private String weapon = "MachineGun"; 
 
        public TankGunner (TankCommander commander) {
                this.commander = commander;
                this.commander.setGunner(this);
        }
 
        public void fire(String target) {
                System.out.println("Gunner ["+weapon+"]: " + target + " is under fire!");
                commander.noTarget(); // target is destroyed 
        }
 
        public void stopFire() {
                System.out.println("Gunner ["+weapon+"]: Fire is stoped.");
        }
 
        public void setWeapon(String weapon) {
                this.weapon = weapon;
        }
}
 
// Colleague
public class TankLoader {
        private TankCommander commander;
 
        public TankLoader (TankCommander commander) {
                this.commander = commander;
                this.commander.setLoader(this);
        }
 
        public String prepareWeapon(String target) {
                String weapon = "MachineGun";
                if (target.equals("armored")) {
                        weapon = "Cannon";
                }
                System.out.println("Loader: " + weapon + " is ready!");
                return weapon;
        }
}

Джерела [ред.]

Література [ред.]

Алан Шаллоуей, Джеймс Р. Тротт Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М.: «Вильямс», 2002. — 288 с. — ISBN 0-201-71594-5