Bridge
Bridge — структурний патерн: розʼєднати абстракцію (що робимо) і реалізацію (як саме) у дві окремі ієрархії, щоб вони могли змінюватись незалежно. Уникає «декартового добутку» класів, коли треба комбінувати два виміри варіативності.
Метафора
Section titled “Метафора”Пульт і телевізор. Пульт — абстракція (кнопки «гучніше», «канал вгору», «меню»). Телевізор — реалізація (Samsung, LG, Sony). Пульти відрізняються формою/кількістю кнопок; телевізори — протоколами і логікою. Розʼєднаний дизайн дозволяє мати будь-який пульт для будь-якого телевізора, без N × M спеціальних комбінацій.
Коли застосовувати
Section titled “Коли застосовувати”- Є два виміри варіативності, що множаться один на одного (наприклад, тип документа × формат виводу: інвойс/замовлення/відвантаження × PDF/XLSX/email).
- Хочеш уникнути вибуху класів
ClassAB,ClassAC,ClassBB,ClassBC… - Абстракція і реалізація мають різні життєві цикли.
- Треба підміняти реалізацію у runtime.
Bridge vs Adapter
Section titled “Bridge vs Adapter”Ззовні схожі (обʼєкт тримає посилання на інший обʼєкт):
- Adapter — постфактум перекладає інтерфейс існуючого класу. Реактивний.
- Bridge — наперед спроектований поділ на дві ієрархії. Проактивний.
ABAP-реалізація
Section titled “ABAP-реалізація”Приклад: сповіщення (notifications). Два виміри:
- Тип: звичайне, важливе, urgent
- Канал: email, SMS, Telegram
Без Bridge — 3 × 3 = 9 класів. З Bridge — 3 + 3 = 6.
" Реалізація (канал доставки) — окрема ієрархіяINTERFACE zif_delivery_channel. METHODS send IMPORTING iv_to TYPE string iv_subject TYPE string iv_body TYPE string.ENDINTERFACE.
CLASS zcl_channel_email DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES zif_delivery_channel.ENDCLASS.CLASS zcl_channel_email IMPLEMENTATION. METHOD zif_delivery_channel~send. " cl_bcs_message ... ENDMETHOD.ENDCLASS.
CLASS zcl_channel_sms DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES zif_delivery_channel.ENDCLASS.
CLASS zcl_channel_telegram DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES zif_delivery_channel.ENDCLASS.
" Абстракція (тип повідомлення) — своя ієрархія, тримає каналCLASS zcl_notification DEFINITION PUBLIC ABSTRACT. PUBLIC SECTION. METHODS: constructor IMPORTING io_channel TYPE REF TO zif_delivery_channel, send IMPORTING iv_to TYPE string iv_text TYPE string. PROTECTED SECTION. DATA mo_channel TYPE REF TO zif_delivery_channel.ENDCLASS.
CLASS zcl_notification IMPLEMENTATION. METHOD constructor. mo_channel = io_channel. ENDMETHOD. METHOD send. " дефолт — переозначать нащадки mo_channel->send( iv_to = iv_to iv_subject = 'Info' iv_body = iv_text ). ENDMETHOD.ENDCLASS.
" Конкретні «абстракції»CLASS zcl_notification_normal DEFINITION PUBLIC FINAL INHERITING FROM zcl_notification. PUBLIC SECTION. METHODS send REDEFINITION.ENDCLASS.CLASS zcl_notification_normal IMPLEMENTATION. METHOD send. mo_channel->send( iv_to = iv_to iv_subject = 'Інформація' iv_body = iv_text ). ENDMETHOD.ENDCLASS.
CLASS zcl_notification_urgent DEFINITION PUBLIC FINAL INHERITING FROM zcl_notification. PUBLIC SECTION. METHODS send REDEFINITION.ENDCLASS.CLASS zcl_notification_urgent IMPLEMENTATION. METHOD send. mo_channel->send( iv_to = iv_to iv_subject = '[URGENT] Терміново' iv_body = |! ! ! { iv_text } ! ! !| ). mo_channel->send( iv_to = iv_to iv_subject = 'Re: [URGENT]' iv_body = 'Повторне' ). ENDMETHOD.ENDCLASS.Використання:
" urgent emailDATA(lo_1) = NEW zcl_notification_urgent( io_channel = NEW zcl_channel_email( ) ).lo_1->send( iv_to = 'admin@company.com' iv_text = 'Server down' ).
" normal telegramDATA(lo_2) = NEW zcl_notification_normal( io_channel = NEW zcl_channel_telegram( ) ).lo_2->send( iv_to = '@chat_id' iv_text = 'Report ready' ).Нова реалізація (WhatsApp, Slack) — новий клас каналу, жодна зміна у ієрархії notification. Новий тип сповіщення (warning) — один клас, працює з усіма каналами.
SAP-специфіка
Section titled “SAP-специфіка”- CL_BCS_MESSAGE +
cl_document_bcs— SAP робить bridge: повідомлення (документ) окремо, спосіб відправки (email/fax/print) — окремо. - Persistence Service (
cl_os_state) + class persistence — розділення класу сутності від способу зберігання. - Printing Architecture — логічні принтери (device types) як реалізація, документ як абстракція.
Підводні камені
Section titled “Підводні камені”- Не плутай з простим DI. Якщо в класі просто є
io_dependency TYPE REF TO zif_foo— це ще не Bridge, це просто залежність. Bridge — про дві ієрархії, що розвиваються незалежно. - Передчасне ускладнення. Якщо реалізація одна і ніколи не буде двох — Bridge додає шар без вигоди. Чекай доки не зʼявиться друга реалізація.
- Обовʼязки замазані. Чітко визнач: що робить абстракція (логіка типу повідомлення), а що — реалізація (механіка каналу). Інакше повториш код в обох ієрархіях.
Коли НЕ використовувати
Section titled “Коли НЕ використовувати”- Один вимір варіативності — бери Strategy або просто наслідування.
- Два виміри, але невеликі (2×2=4 класи) — плоскі 4 класи зрозуміліші.
- Варіативність фіксована — бери композицію без окремих ієрархій.