Что такое паттерн Bridge?

Ответ

Паттерн 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

Преимущества:

  • Принцип разделения ответственности: Абстракция и реализация живут в разных классах.
  • Расширяемость: Можно добавлять новые абстракции и реализации независимо.
  • Сокрытие деталей: Клиентский код работает с абстракциями.

Ответ 18+ 🔞

Э, слушай, вот есть такая штука — паттерн Bridge, или Мост. Ну, это не про то, чтобы на речке переправу строить, а про архитектуру кода, ёпта. Суть в том, чтобы абстракцию и её реализацию развести по разным углам, как двух дерущихся котов. Чтобы они друг другу мозг не выносили и менялись независимо.

А нахуя это надо? Ну представь, у тебя есть устройства — телек, радио, и пульты к ним — простой, продвинутый. Если тупо плодить классы на каждый чих, получится овердохуища комбинаций: BasicTVRemote, AdvancedTVRemote, BasicRadioRemote… Аж волнение ебать, какой бардак! Мост же позволяет этого избежать, разделив логику.

Смотри, как это на 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

И в чём, блядь, профит?

  • Принцип "не лезь не в своё дело": Абстракция и реализация сидят по разным комнатам, не мешая друг другу.
  • Расширяемость на уровне бога: Хочешь — новую железяку добавляй, хочешь — новый пульт придумывай. Всё независимо, как будто на дворе 2002-й год и у каждого свой трек в наушниках.
  • Сокрытие деталей, как грехов: Клиентский код работает с абстракциями, а что там внутри творится — ему да похуй. Главное, чтобы кнопки нажимались.

Вот и весь мост, ебать мои старые костыли. Не такой уж и страшный, правда?