Что такое шаблон проектирования Bridge (Мост)?

«Что такое шаблон проектирования Bridge (Мост)?» — вопрос из категории Паттерны, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Bridge — это структурный шаблон проектирования, который разделяет абстракцию (интерфейс или высокоуровневую логику) и её реализацию (низкоуровневые детали) в отдельные иерархии классов. Это позволяет изменять их независимо друг от друга, используя композицию вместо наследования.

Проблема, которую решает Мост: Избежать «разбухания» класса из-за комбинаторного взрыва подклассов (например, CircleRed, CircleBlue, SquareRed, SquareBlue).

Ключевые компоненты:

  • Abstraction (Абстракция): Определяет высокоуровневый интерфейс и содержит ссылку на объект Implementor.
  • RefinedAbstraction (Уточнённая абстракция): Расширяет интерфейс, определённый Abstraction.
  • Implementor (Реализатор): Определяет интерфейс для низкоуровневых операций.
  • ConcreteImplementor (Конкретный реализатор): Содержит конкретную реализацию интерфейса Implementor.

Пример: Фигуры и цвета

// 1. Иерархия Реализации (Цвета)
interface Color {
    String fill();
}

class Red implements Color {
    @Override
    public String fill() { return "красным"; }
}

class Blue implements Color {
    @Override
    public String fill() { return "синим"; }
}

// 2. Иерархия Абстракции (Фигуры)
abstract class Shape {
    protected Color color; // Композиция! Мост между абстракцией и реализацией

    public Shape(Color color) { this.color = color; }

    abstract String draw();
}

class Circle extends Shape {
    public Circle(Color color) { super(color); }

    @Override
    public String draw() {
        return "Рисую круг, залитый " + color.fill();
    }
}

class Square extends Shape {
    public Square(Color color) { super(color); }

    @Override
    public String draw() {
        return "Рисую квадрат, залитый " + color.fill();
    }
}

// Использование
Color red = new Red();
Shape redCircle = new Circle(red);
System.out.println(redCircle.draw()); // Рисую круг, залитый красным

Shape blueSquare = new Square(new Blue());
System.out.println(blueSquare.draw()); // Рисую квадрат, залитый синим

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

  • Разделение ответственности: Абстракция и реализация развиваются независимо.
  • Принцип открытости/закрытости: Можно добавлять новые абстракции и реализации, не меняя существующий код.
  • Сокрытие деталей реализации от клиентского кода.

Применение: Драйверы устройств, GUI-фреймворки (отделение платформо-зависимой части), API, работающие с разными типами баз данных.