Статьи

Учебное пособие по мостовым образцам с примерами Java

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

Мост в реальном мире 

Отображение разных форматов изображений в разных операционных системах является хорошим примером паттерна Bridge. У вас могут быть разные абстракции изображений для изображений JPEG и PNG. Структура образа одинакова во всех операционных системах, но способ ее просмотра (реализация) различен для каждой ОС. Это тот тип развязки, который позволяет шаблон Bridge.

Refcard Designs Patterns
Для лучшего обзора самых популярных шаблонов дизайна, лучше всего начать с Refcard Designs Patterns от DZone

Образец Моста

Паттерн «Мост» известен как структурный паттерн, так как он используется для формирования больших структур объектов во многих разнородных объектах. Определение Моста, представленное в оригинальной книге «Банды четырех» на DesignPatterns, гласит: 

Отсоедините абстракцию от ее реализации, чтобы они могли независимо изменяться

Давайте посмотрим на определение диаграммы, прежде чем углубляться в детали.

Абстракция определяет абстракцию и поддерживает ссылку на разработчика. RefinedAbstraction предоставляет расширение для Abstraction, обычно добавляя дополнительные методы, которые предоставляют разные способы получения одной и той же функциональности. Интерфейс Implementor определяет интерфейс для классов реализации (классы ConcreateImplementor).

RefinedAbstractions реализованы в терминах абстракции, а не интерфейса реализации. Это означает, что детали реализации скрыты от клиента. Шаблон аналогичен шаблону Adapter, за исключением того, что шаблон Bridge отделяет интерфейс от реализации. 

Буду ли я использовать этот шаблон?

Шаблон Bridge следует использовать, когда класс и его функции часто меняются. Шаблон моста также можно рассматривать как два уровня абстракции. Когда абстракции и реализации не должны быть связаны во время компиляции и должны быть независимо расширяемыми, следует использовать шаблон. 

В частности, этот шаблон полезен в графических инструментах, которые должны работать на нескольких платформах. Вы увидите это в AWT, где компонент имеет одноранговый компонент, который выполняет специфические для ОС операции. Также у платформы Collections есть примеры интерфейса моста: ArrayList и LinkedList реализованы List. И List предоставляет общие методы для добавления, удаления или проверки размера. 

Так как это работает в Java?

Вот образец в действии, используя пример дистанционного управления из Head First Design Patterns. 

Во-первых, у нас есть интерфейс реализации ТВ: 

//Implementor public interface TV{public void on();public void off(); public void tuneChannel(int channel);}

 И затем мы создаем две конкретные реализации — одну для Sony и одну для Philips: 

//Concrete Implementor public class Sony implements TV{public void on(){//Sony specific on}public void off(){//Sony specific off}public void tuneChannel(int channel);{//Sony specific tuneChannel}}//Concrete Implementor public class Philips implements TV{public void on(){//Philips specific on}public void off(){//Philips specific off}public void tuneChannel(int channel);{//Philips specific tuneChannel}}

 Эти классы имеют дело с конкретными реализациями телевизора от каждого поставщика. 

Теперь мы создаем абстракцию удаленного управления для управления телевизором:

//Abstractionpublic abstract class RemoteControl{   private TV implementor;          public void on()   {      implementor.on();   }   public void off()   {      implementor.off();   }      public void setChannel(int channel)   {   implementor.tuneChannel(channel);   }}

 Поскольку пульт дистанционного управления содержит ссылку на телевизор, он может передавать методы через интерфейс. Но для чего нам нужен более конкретный пульт дистанционного управления — тот, который имеет кнопки + / — для перемещения по каналам? Все, что нам нужно сделать, это расширить нашу абстракцию RemoteControl, чтобы она содержала следующие понятия: 

//Refined abstractionpublic class ConcreteRemote extends RemoteControl{   private int currentChannel;       public void nextChannel()   {       currentChannel++;   setChannel(currentChannel);   }      public void prevChannel()   {       currentChannel--;   setChannel(currentChannel);   }      }

Остерегайтесь недостатков

Одним из основных недостатков этого шаблона является то, что при обеспечении гибкости он увеличивает сложность. Также возможны проблемы с производительностью при перенаправлении сообщений — абстракция должна передавать сообщения реализатору для выполнения операции.

Следующий

Больше моделей позже на этой неделе — мы близки к концу сейчас!

Наслаждайтесь всей серией «Design Patterns Uncovered»:

Образцы творчества

Структурные паттерны

Поведенческие образцы