Ответ
Паттерн Bridge (Мост) — это структурный шаблон проектирования, который разделяет абстракцию и её реализацию на две отдельные иерархии классов. Это позволяет изменять их независимо друг от друга.
Зачем он нужен? Чтобы избежать взрывного роста количества классов при комбинации различных абстракций и реализаций. Например, у вас есть разные типы устройств (TV, Radio) и разные типы пультов (Basic, Advanced). Вместо создания классов BasicTVRemote, AdvancedTVRemote, BasicRadioRemote и т.д., Bridge разделяет эту логику.
Пример на PHP:
// Иерархия реализации (устройства)
interface Device {
public function isEnabled(): bool;
public function enable(): void;
public function disable(): void;
public function getVolume(): int;
public function setVolume(int $percent): void;
}
class TV implements Device {
private bool $enabled = false;
private int $volume = 20;
public function isEnabled(): bool { return $this->enabled; }
public function enable(): void { $this->enabled = true; }
public function disable(): void { $this->enabled = false; }
public function getVolume(): int { return $this->volume; }
public function setVolume(int $percent): void { $this->volume = $percent; }
}
// Иерархия абстракции (пульты)
abstract class RemoteControl {
protected Device $device;
public function __construct(Device $device) {
$this->device = $device;
}
public function togglePower(): void {
if ($this->device->isEnabled()) {
$this->device->disable();
echo "Device turned off.n";
} else {
$this->device->enable();
echo "Device turned on.n";
}
}
abstract public function volumeUp(): void;
}
class BasicRemote extends RemoteControl {
public function volumeUp(): void {
$current = $this->device->getVolume();
$this->device->setVolume($current + 10);
echo "Volume set to: " . $this->device->getVolume() . "n";
}
}
// Использование
$tv = new TV();
$remote = new BasicRemote($tv);
$remote->togglePower(); // Device turned on.
$remote->volumeUp(); // Volume set to: 30
Преимущества:
- Принцип разделения ответственности: Абстракция и реализация живут в разных классах.
- Расширяемость: Можно добавлять новые абстракции и реализации независимо.
- Сокрытие деталей: Клиентский код работает с абстракциями.