Мост (Bridge)

Метафора

 

Представим ситуацию, когда вам требуется работать на разных автомобилях, однако садясь в новый автомобиль вам уже желательно знать, как им управлять. Таким образом, Вы сталкиваетесь с паттерном «мост». С одной стороны, вы имеете множество различных автомобилей (разные модели и марки), но среди них есть общая абстракция (интерфейс) в виде руля, педалей, коробки передач и так далее. Таким образом, мы задаем как-бы правила изготовления автомобилей, по которым мы можем создавать любые их виды, но за счет сохранения общих правил взаимодействия с ними, мы можем одинаково управлять каждым из них. «Мостом» в данном случае является пара двух «объектов»: конкретного автомобиля и правил взаимодействия с этим (и любым другим) автомобилем.

 

Назначение

 

Позволяет отделить абстракцию от реализации так, что и то, и другое можно было бы изменять независимо, путём помещения абстракции и реализации в отдельные иерархии классов.

Представим некоторую классическую схему проектирования классов – есть базовый абстрактный класс, определяющий интерфейс и его наследники, реализующие данный интерфейс. У данной схемы есть определенные недостатки:

  • Реализация жестко привязана к интерфейсу, изменить реализацию объекта во время выполнения уже нельзя.
  • Если число наследников велико, систему становится сложно поддерживать.

Используя паттерн мост, мы избавимся от этих недостатков.

 

Диаграмма

 

Мост

Мост

 

Пример

 

Предположим у нас с Вами есть некоторые классы для формирования PDF отчётов: OneReport, TwoReport:

sample1

 

Каждый из них наследуется от базового класса Report и переопределяет методы get_data и write_data, при этом write_data формирует PDF формуляр, а get_data содержит бизнес-логику получения данных для вывода.

В один прекрасный момент к нам приходит клиент и говорит: «Хочу вывод в DOC и в XML». Самое первое что приходит в голову это наследование:

sample2

 

Вывод PDF мы уберём из отчётов. Создадим по наследнику от каждого отчёта и переопределим метод вывода отчёта для конкретного формата. Как понятно из схемы, у нас появилась другая проблема — сложность поддержки большого числа классов.

Решить её мы можем, несколько изменив наше решение, применив паттерн мост:

bridge_sample

Реализацию, отвечающую за вывод данных, мы вынесли в отдельную иерархию классов — Printer. В клиенте при определении объекта OneReport или TwoReport мы будет внедрять ему реализацию конкретного принтера, который умеет печатать в нужном клиенту формате.

Пример на ABAP:

 

2 комментария

  1. При реализации классов отчетов нет смысла переопределять метод write_data(), т.к. функционал у него один и тот же. Не проще ли его оставить на уровне родительского отчета? Или это для наглядности сделано?

Добавить комментарий для Svirinstel Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *