- 1. Цели
- 2. Проблематика
- 3. Мотивация
- 4. Обсуждение
- 5. Структура
- 6. Пример
- 7. Контрольный список
- 8. Эмпирические правила
Цели
- Отделите абстракцию от ее реализации, чтобы они могли изменяться независимо друг от друга.
- Создание публичного интерфейса в иерархии наследования и реализация в своей собственной иерархии наследования.
- Помимо инкапсуляции использование изоляции
Проблематика
«Укрепление программных связей» путем использования подкласса абстрактного базового класса для обеспечения альтернативных реализаций. Это блокирует привязку ко времени компиляции между интерфейсом и реализацией. Абстракция и реализация не могут быть независимо расширены или переопределены.
Мотивация
Рассмотрим область «планирования потоков».
Существует два типа планировщиков потоков, два типа операционных систем или «платформы». Учитывая этот подход к специализации, мы должны определить класс для каждого варианта из этих двух вариаций. Если мы добавим новую платформу (скажем ... виртуальную машину Java), как бы выглядела наша иерархия?
Что, если у нас было три вида планировщиков потоков и четыре вида платформ? Что делать, если у нас было пять видов планировщиков потоков и десять видов платформ? Количество классов, которые мы должны были бы определить, является результатом количества схем планирования и количества платформ.
Шаблон проектирования Bridge предлагает рефакторинг этой экспоненциально взрывоопасной иерархии наследования в две ортогональные иерархии - одну для абстракций, независимых от платформы, а другую для зависимых от платформы реализаций.
Обсуждение
Разложите интерфейс компонента и реализацию в ортогональные иерархии классов. Класс интерфейса содержит указатель на абстрактный класс реализации. Этот указатель инициализируется экземпляром конкретного класса, но все последующее взаимодействие класса интерфейса с классом реализации ограничивается абстракцией, поддерживаемой в базовом классе реализации. Клиент взаимодействует с классом интерфейса и, в свою очередь, «делегирует» все запросы реализации класса.
Объект интерфейса - это «обработчик», известный и используемый клиентом; в то время как объект реализации или «тело» безопасно инкапсулирован, чтобы гарантировать, что он может продолжать развиваться или полностью заменяться (или использоваться во время выполнения.
Используйте шаблон Bridge, если:
- Вы хотите, чтобы реализация привязывалась в рантайме
- у вас есть рост количества классов, возникающих в результате сопряженного интерфейса и многочисленных реализаций,
- вы хотите разделить реализацию между несколькими объектами,
- вам нужно сопоставить ортогональные иерархии классов.
Последствия включают:
- декомпозициб интерфейса объекта
- улучшенная расширяемость (вы можете расширить (например, подкласс) иерархии абстракции и реализации независимо),
- скрытие деталей от клиентов.
Мост является синонимом идиомы «обработчик/тело». Это механизм проектирования, который инкапсулирует класс реализации внутри класса интерфейса. Первый - это тело, а второе - обработчик. Обработчик рассматривается пользователем как фактический класс, но работа выполняется в теле. «Идиома класса handle/body может использоваться для декомпозиции сложной абстракции на более мелкие, более управляемые классы. Идиома может отражать совместное использование одного ресурса несколькими классами, которые контролируют доступ к нему (например, подсчет ссылок)».
Структура
Клиент не хочет иметь дело с зависимыми от платформы деталями. Шаблон Bridge инкапсулирует эту сложность за абстракционную «обертку».
Bridge подчеркивает идентификацию и разделение абстракции «интерфейса» от абстракции «реализации».
Пример
Шаблон Bridge отделяет абстракцию от ее реализации, так что они могут варьироваться независимо друг от друга. Примером Моста является бытовой выключатель, управляющий огнями, потолочными вентиляторами и т. Д. Целью переключателя является включение или выключение устройства. Фактически переключатель может быть реализован как тянущая цепь, простой двухпозиционный переключатель или различные диммерные переключатели.
Контрольный список
- Решите, существуют ли в приложении две возможных ортогональных иерархии классов. Этими независимыми иерархиями могут быть: абстракция/платформа, или домен/инфраструктура, или интерфейс/интерфейс, или интерфейс/реализация.
- Разработайте разделение проблем: чего хочет клиент и что предоставляют платформы.
- Создайте платформенный интерфейс, который минимален, необходим и достаточен. Его цель - отделить абстракцию от платформы.
- Определить производный класс этого интерфейса для каждой платформы.
- Создайте базовый класс абстракции, который имеет «объект платформы» и делегирует ему платформенно-ориентированную функциональность.
- Определите специализации класса абстракции, если это необходимо.
Эмпирические правила
- Адаптер позволяет работать c классами после того, как они разработаны; Мост заставляет их работать до того, как они были разработаны.
- Мост разработан заранее, чтобы абстракция и реализация менялись независимо. Адаптер модернизирует код, чтобы классы работали вместе.
- State, Strategy, Bridge (и до некоторой степени Adapter) имеют аналогичные структуры решений. Все они разделяют элементы идиомы «обработчик/тело». Они различаются по намерениям - то есть, они решают разные проблемы.
- Структура State и Bridge идентична (за исключением того, что Bridge допускает иерархии классов, тогда как State допускает только одно). Эти два шаблона используют одну и ту же структуру для решения различных задач: State позволяет изменять поведение объекта вместе с его состоянием, в то время как намерение Моста состоит в том, чтобы отделить абстракцию от его реализации, чтобы они могли варьироваться независимо.
- Если интерфейсы классов делегируют создание своих классов реализации (вместо того, чтобы напрямую создавать / связывать себя), тогда в проекте обычно используется шаблон Abstract Factory для создания реализации объектов.