Перейти до вмісту

Facade

Facade — структурний патерн: фасадний клас, що надає один простий метод замість вручну координувати кілька класів з підсистеми. Клієнт перестає знати внутрішню структуру — бачить тільки фасад.

Панель водія авто: кермо, педалі, важіль коробки. За ними — мотор, коробка передач, гідропривід, ECU, десятки сенсорів. Водій не лізе під капот — він користується фасадом. І якщо завтра мотор поміняти з ДВЗ на електро — кермо та педалі залишаться тими ж. Фасад захищає від змін.

  • Підсистема складна — клієнту щоразу доводиться памʼятати послідовність викликів.
  • Клієнт не повинен залежати від внутрішньої структури підсистеми — фасад розриває звʼязок.
  • Треба мати одну точку входу для типового сценарію, залишивши можливість обходу фасада для рідкісних випадків.
  • Треба декомпозувати монолітний клас без зламу клієнтів — фасад залишає той самий API.

Класичний приклад — оформлення замовлення, що вимагає координації трьох сервісів:

INTERFACE zif_inventory.
METHODS reserve
IMPORTING it_items TYPE zty_items
RAISING zcx_out_of_stock.
ENDINTERFACE.
INTERFACE zif_payment.
METHODS charge
IMPORTING iv_customer TYPE kunnr
iv_amount TYPE p
RAISING zcx_payment_failed.
ENDINTERFACE.
INTERFACE zif_shipping.
METHODS schedule
IMPORTING iv_customer TYPE kunnr
it_items TYPE zty_items
RAISING zcx_shipping_unavailable.
ENDINTERFACE.
" Фасад — один метод замість трьох
CLASS zcl_order_facade DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING io_inventory TYPE REF TO zif_inventory
io_payment TYPE REF TO zif_payment
io_shipping TYPE REF TO zif_shipping,
place_order
IMPORTING iv_customer TYPE kunnr
it_items TYPE zty_items
RAISING zcx_order_failed.
PRIVATE SECTION.
DATA:
mo_inventory TYPE REF TO zif_inventory,
mo_payment TYPE REF TO zif_payment,
mo_shipping TYPE REF TO zif_shipping.
ENDCLASS.
CLASS zcl_order_facade IMPLEMENTATION.
METHOD constructor.
mo_inventory = io_inventory.
mo_payment = io_payment.
mo_shipping = io_shipping.
ENDMETHOD.
METHOD place_order.
TRY.
mo_inventory->reserve( it_items ).
mo_payment->charge( iv_customer = iv_customer
iv_amount = calc_total( it_items ) ).
mo_shipping->schedule( iv_customer = iv_customer
it_items = it_items ).
CATCH zcx_out_of_stock zcx_payment_failed zcx_shipping_unavailable
INTO DATA(lx).
RAISE EXCEPTION NEW zcx_order_failed( ix_previous = lx ).
ENDTRY.
ENDMETHOD.
ENDCLASS.

Використання:

DATA(lo_order) = NEW zcl_order_facade(
io_inventory = NEW zcl_inventory( )
io_payment = NEW zcl_payment( )
io_shipping = NEW zcl_shipping( ) ).
lo_order->place_order( iv_customer = '4711' it_items = lt_items ).

Клієнт не знає, що для розміщення замовлення треба три кроки у правильному порядку з правильними даними. Це знає фасад.

  • Фасад — не єдиний вхід. Він — зручний вхід. Якщо клієнту треба щось рідкісне, він може обійти фасад і звертатися до сервісів напряму.
  • Фасад — не додає бізнес-логіки. Він координує, а не містить правила. Калькуляцію знижки робить zcl_payment, не фасад.
  • Транзакційність. Якщо payment успішний, а shipping впав — що робити з платежем? Фасад — природне місце для компенсуючих дій або SAP LUW-управління. Див. SAP LUW.
  • BAPI — класичні фасади SAP-стандарту. BAPI_SALESORDER_CREATEFROMDAT2 за одним викликом координує перевірки, блокування, створення, коміт.
  • cl_salv_table — фасад над cl_salv_model_table + cl_salv_columns_table + десятком інших класів.
  • Released API в S/4HANA Cloud — фасад над внутрішньою складністю: клієнт бачить CL_*_SRV клас, всередині — ієрархія.
  • Orchestration-клас (наприклад zcl_order_facade) — типове місце для обʼєднання кількох сервісів (inventory + payment + shipping) за одним викликом.
FacadeAdapterMediator
МетаСпрощення підсистемиПереклад інтерфейсуКоординація компонентів
НапрямНазовні (клієнт → підсистема)Перекладає двосторонньоВсередині (компонент ↔ компонент)
Існуючий інтерфейсЗалишається доступнимЗамінює/обгортаєЗамінює прямі звʼязки
  • Прихована складність. Фасад ховає послідовність, але не магію. Клієнт досі повинен знати, що робить place_order — і що саме воно не може відкотити payment автоматично.
  • Фасад на фасад. Коли в проекті зʼявляється zcl_order_facade_ext, що обгортає zcl_order_facade — це сигнал, що перший фасад некоректний. Почни спочатку.
  • Не ховай все. Якщо клієнту треба inventory->check_stock, не додавай facade->check_stock — це просочування підсистеми. Краще експонувати inventory окремо.

Коли НЕ використовувати

Section titled “Коли НЕ використовувати”
  • Підсистема — один клас. Фасад на фасад без сенсу.
  • Клієнту потрібен гнучкий доступ до всіх деталей — фасад тільки заважатиме.
  • Послідовність викликів — не стабільна, часто змінюється. Фасад доведеться перероблювати щоразу.