Bridge (Мост)¶
Категория: структурный паттерн.
Проблема¶
Класс нужно расширять в двух независимых измерениях, например по типу фигуры и способу её отрисовки. Если выразить обе оси наследованием, понадобятся классы для каждой комбинации (RasterCircle, VectorCircle, RasterSquare, ...), и их число будет перемножаться.
Решение¶
Одна ось остаётся иерархией абстракций, а вторая выносится в иерархию реализаций. Абстракция хранит ссылку на реализацию и делегирует ей низкоуровневую работу. Обе иерархии можно расширять независимо и комбинировать во время выполнения.
Термины «абстракция» и «реализация» здесь обозначают роли паттерна, а не обязательно abstract class и interface языка C#.
Структура¶
Abstraction- высокоуровневая логика, использующая объектImplementor.RefinedAbstraction- дополнительные варианты высокоуровневого поведения.Implementor- контракт низкоуровневых операций.ConcreteImplementor- платформенная или технологическая реализация этих операций.
Когда применять¶
- Класс изменяется по двум независимым причинам, и число комбинаций подклассов растёт.
- Нужно отделить предметную логику от платформы, драйвера, хранилища или способа визуализации.
- Реализацию требуется выбирать или заменять во время выполнения.
Плюсы¶
- Две оси расширения развиваются независимо вместо комбинаторного роста подклассов.
- Платформенные детали изолированы от клиентского кода.
- Реализацию можно подменять через композицию и удобно тестировать отдельно.
Минусы¶
- Для простой стабильной модели добавляет лишний уровень косвенности.
- Границу между абстракцией и реализацией нужно выбрать осмысленно; неудачное разделение только размазывает ответственность.
Отличие от Adapter и Strategy¶
Adapter обычно подключают после появления несовместимых интерфейсов, чтобы заставить существующие классы работать вместе. Bridge закладывают заранее, чтобы две части системы развивались независимо. Strategy похож технически - тоже подменяет объект поведения, - но решает поведенческую задачу выбора алгоритма, тогда как Bridge прежде всего разделяет структуру на две иерархии.
Пример в .NET¶
- Отделение провайдера хранения от репозитория предметной области.
- Абстракции ADO.NET (
DbConnection,DbCommand) и конкретные провайдеры баз данных близки к идее Bridge: высокоуровневый клиентский код работает с общим API, а провайдер выполняет платформенную работу.
Источник для сверки структуры: Refactoring.Guru - Bridge.