TODO: отвалидировать – текст собран автоматически из материалов курса на Google Drive, проверьте формулировки и код.
Перенаправление обеспечивает низкое зацепление между классами, назначая обязанности по их взаимодействию дополнительному объекту-посреднику.
Яркий пример – Controller из триады MVC: представление не обращается к модели напрямую.
// Прямая связь: каждый модуль знает про каждый
public class OrderModule
{
private readonly WarehouseModule _warehouse = new();
private readonly BillingModule _billing = new();
}
// Через посредника: модули знают только о нём
public class OrderCoordinator
{
public void Place(Order order)
{
_warehouse.Reserve(order);
_billing.Charge(order);
}
}
// Прямая связь: каждый модуль знает про каждый
class OrderModule {
private:
WarehouseModule warehouse_;
BillingModule billing_;
};
// Через посредника: модули знают только о нём
class OrderCoordinator {
public:
OrderCoordinator(IWarehouse& warehouse, IBilling& billing)
: warehouse_(warehouse), billing_(billing) {}
void Place(const Order& order) {
warehouse_.Reserve(order);
billing_.Charge(order);
}
private:
IWarehouse& warehouse_;
IBilling& billing_;
};
// Прямая связь: каждый модуль знает про каждый
type OrderModule struct {
warehouse *WarehouseModule
billing *BillingModule
}
// Через посредника: модули знают только о нём
type OrderCoordinator struct {
warehouse Warehouse
billing Billing
}
func (c *OrderCoordinator) Place(order Order) error {
if err := c.warehouse.Reserve(order); err != nil {
return err
}
return c.billing.Charge(order)
}
# Прямая связь: каждый модуль знает про каждый
class OrderModule:
def __init__(self) -> None:
self._warehouse = WarehouseModule()
self._billing = BillingModule()
# Через посредника: модули знают только о нём
class OrderCoordinator:
def __init__(self, warehouse: Warehouse, billing: Billing) -> None:
self._warehouse = warehouse
self._billing = billing
def place(self, order: Order) -> None:
self._warehouse.reserve(order)
self._billing.charge(order)
// Прямая связь: каждый модуль знает про каждый
class OrderModule {
private readonly warehouse = new WarehouseModule();
private readonly billing = new BillingModule();
}
// Через посредника: модули знают только о нём
class OrderCoordinator {
constructor(
private readonly warehouse: Warehouse,
private readonly billing: Billing,
) {}
place(order: Order): void {
this.warehouse.reserve(order);
this.billing.charge(order);
}
}
// Прямая связь: каждый модуль знает про каждый
public class OrderModule {
private final WarehouseModule warehouse = new WarehouseModule();
private final BillingModule billing = new BillingModule();
}
// Через посредника: модули знают только о нём
public class OrderCoordinator {
private final Warehouse warehouse;
private final Billing billing;
public OrderCoordinator(Warehouse warehouse, Billing billing) {
this.warehouse = warehouse;
this.billing = billing;
}
public void place(Order order) {
warehouse.reserve(order);
billing.charge(order);
}
}
// Прямая связь: каждый модуль знает про каждый
class OrderModule {
private val warehouse = WarehouseModule()
private val billing = BillingModule()
}
// Через посредника: модули знают только о нём
class OrderCoordinator(
private val warehouse: Warehouse,
private val billing: Billing,
) {
fun place(order: Order) {
warehouse.reserve(order)
billing.charge(order)
}
}
Цена принципа
Посредник – это лишний уровень косвенности. Он снижает зацепление, но усложняет чтение: чтобы понять, что произойдёт, приходится идти по цепочке. Тот же компромисс подробно разбирается в паттерне Mediator.