Prototype
Prototype — породжуючий патерн: замість створювати обʼєкт нуля (з важкою ініціалізацією — зверненнями до БД, RFC-викликами, побудовою дерев), ти клонуєш уже готовий зразок.
Метафора
Section titled “Метафора”Шаблон договору: замість писати новий договір з нуля, ти береш готовий шаблон і підправляєш у ньому імена й суми. Так само з обʼєктом — клонуєш «заповнений» prototype і тільки коригуєш поля, що відрізняються.
Коли застосовувати
Section titled “Коли застосовувати”- Ініціалізація дорога: RFC-дзвінок, важкий SELECT, побудова обʼєктної структури (дерева XML, deeply nested structures).
- Треба багато однотипних обʼєктів, що відрізняються в кількох полях.
- Клієнту не треба знати конкретний клас — йому потрібен тільки метод
clone( ). - Треба зробити snapshot стану, який потім може змінюватись незалежно.
ABAP-реалізація
Section titled “ABAP-реалізація”ABAP не має вбудованого clone( ) як Java. Є варіанти:
Варіант 1 — власний clone( ) метод
Section titled “Варіант 1 — власний clone( ) метод”Явний контракт через інтерфейс:
INTERFACE zif_cloneable. METHODS clone RETURNING VALUE(ro_clone) TYPE REF TO zif_cloneable.ENDINTERFACE.
CLASS zcl_request DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES zif_cloneable.
METHODS: constructor IMPORTING iv_endpoint TYPE string is_state TYPE zty_state OPTIONAL,
get_state RETURNING VALUE(rs_state) TYPE zty_state, set_body IMPORTING iv_body TYPE string.
PRIVATE SECTION. DATA: mv_endpoint TYPE string, ms_state TYPE zty_state.ENDCLASS.
CLASS zcl_request IMPLEMENTATION. METHOD constructor. mv_endpoint = iv_endpoint. IF is_state IS SUPPLIED. ms_state = is_state. ELSE. " дорога ініціалізація — автентифікація, токен, etc ms_state = do_expensive_init( ). ENDIF. ENDMETHOD.
METHOD zif_cloneable~clone. " shallow copy через CORRESPONDING структур/полів ro_clone = NEW zcl_request( iv_endpoint = me->mv_endpoint is_state = me->ms_state ). ENDMETHOD.
METHOD get_state. rs_state = ms_state. ENDMETHOD. METHOD set_body. ms_state-body = iv_body. ENDMETHOD.ENDCLASS.Використання:
DATA(lo_prototype) = NEW zcl_request( iv_endpoint = '/api/sap/orders' ).
" десять однакових запитів з різним body — без повторної авторизаціїDO 10 TIMES. DATA(lo_req) = CAST zcl_request( lo_prototype->zif_cloneable~clone( ) ). lo_req->set_body( build_body( sy-index ) ). lo_req->send( ).ENDDO.Варіант 2 — глибоке копіювання через серіалізацію
Section titled “Варіант 2 — глибоке копіювання через серіалізацію”Коли обʼєкт має складний стан з вкладеними обʼєктами — shallow copy не вистачить:
METHOD zif_cloneable~clone. DATA lv_xml TYPE xstring.
" серіалізація через iXML або CALL TRANSFORMATION CALL TRANSFORMATION id SOURCE src = me RESULT XML lv_xml. CALL TRANSFORMATION id SOURCE XML lv_xml RESULT src = ro_clone.ENDMETHOD.Дорого, але гарантує повне відчеплення клону від оригіналу.
Варіант 3 — CORRESPONDING для DTO
Section titled “Варіант 3 — CORRESPONDING для DTO”Якщо клонується не обʼєкт, а значення-структура — CORRESPONDING + REF:
DATA(ls_copy) = CORRESPONDING ts_order( ls_original ).Не патерн Prototype у GoF-сенсі, але той самий результат для простого випадку.
SAP-специфіка
Section titled “SAP-специфіка”- RAP / EML —
MODIFY ENTITIES ... CREATE FROMфактично клонує стан сутності-прототипу. - Shared Memory Objects (
cl_shm_area) — shared-памʼять часто зберігає прототипи для подальшого копіювання у user-session. - Deep copy через
CL_ABAP_BROKER— у деяких версіях ABAP є helper для глибокого клонування обʼєктів.
Підводні камені
Section titled “Підводні камені”- Не забудь зробити
final. Якщо клас маєclone( )і десь успадковується — нащадок може «забути» переозначити клон і повернути обʼєкт не того типу. - Equals і hash після клону. Якщо є кастомний
equals( ), переконайся, що клон === оригінал за цим методом, або чітко задокументуй інакше. - Імутабельний прототип. Тримай eталонний prototype незмінним. Інакше всі наступні клони отримають підправлені значення, і в коді ніде не видно, коли саме відбулась зміна.
Коли НЕ використовувати
Section titled “Коли НЕ використовувати”- Ініціалізація дешева — звичайний
NEWпростіший і зрозуміліший. - Обʼєкти простому —
CORRESPONDINGнад структурою. - Немає reference-полів — shallow copy тривіальна, патерн не потрібен.