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

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

Посередник (англ. 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.