Декоратор, Decorator — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.
Задача
Объект, который предполагается использовать, выполняет основные функции (Класс lcl_alv). Однако может потребоваться добавить к нему некоторую дополнительную функциональность, которая будет выполняться до, после или даже вместо основной функциональности объекта. В примере ниже функциональность будет вызываться после основной (класс op_pdf).
Декоратор предназначен для динамического добавления объекту новой функциональности. Является гибкой альтернативой механизму наследования, в том числе и множественного.
Данный шаблон используется если необходимо:
- динамически и прозрачно для клиента изменять функциональность объекта;
- (или) реализовать небольшую функциональность, которая в дальнейшем может быть исключена;
- (или) уменьшить число классов, получающихся в результате использования наследования;
- (или) добавить функциональность классу, от которого невозможно наследоваться;
- (или) реализовать аналог множественного наследования, в языках его не поддерживающих.
Реализация ABAP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
REPORT znp_dp_decorator. * Абстрактный класс вывода данных CLASS OUTPUT DEFINITION ABSTRACT. PUBLIC SECTION. METHODS: process_output ABSTRACT. ENDCLASS. * Базовый класс вывода, выводит в ALV формате.. CLASS lcl_alv DEFINITION INHERITING FROM OUTPUT. PUBLIC SECTION. METHODS: process_output REDEFINITION. ENDCLASS. "op_alv DEFINITION * CLASS lcl_alv IMPLEMENTATION. METHOD process_output. WRITE: /(10) SPACE, 'Base class: generating ALV'. ENDMETHOD. "process_output ENDCLASS. * Класс для управления последовательностью вызовов CLASS opdecorator DEFINITION INHERITING FROM OUTPUT. PUBLIC SECTION. METHODS: CONSTRUCTOR IMPORTING io_decorator TYPE REF TO OUTPUT OPTIONAL, process_output REDEFINITION. PRIVATE SECTION. DATA: o_decorator TYPE REF TO OUTPUT. ENDCLASS. CLASS opdecorator IMPLEMENTATION. METHOD CONSTRUCTOR. super->constructor( ). IF io_decorator IS SUPPLIED. me->o_decorator = io_decorator. ENDIF. ENDMETHOD. METHOD process_output. CHECK o_decorator IS BOUND. o_decorator->process_output( ). ENDMETHOD. ENDCLASS. * Класс-декоратор вывода в формате pdf CLASS op_pdf DEFINITION INHERITING FROM opdecorator. PUBLIC SECTION. METHODS: process_output REDEFINITION. ENDCLASS. * CLASS op_pdf IMPLEMENTATION. METHOD process_output. super->process_output( ). " Сперва вызываем предыдущий вывод. WRITE: /(10) SPACE, 'Generating PDF'. ENDMETHOD. ENDCLASS. * Основной класс отчёта CLASS mainapp DEFINITION. PUBLIC SECTION. CLASS-METHODS: run IMPORTING iv_pdf TYPE flag. ENDCLASS. "mainapp DEFINITION * CLASS mainapp IMPLEMENTATION. METHOD run. DATA: lo_decorator TYPE REF TO OUTPUT, lo_pre TYPE REF TO OUTPUT. " Helper Variable * Создаем объект стандартного вывода в ALV CREATE OBJECT lo_decorator TYPE lcl_alv. lo_pre = lo_decorator. " Запоминаем созданный объект, чтобы вставить в цепочку * Создаем класс-декоратор для вывода в PDF IF iv_pdf IS NOT INITIAL. CREATE OBJECT lo_decorator TYPE op_pdf EXPORTING io_decorator = lo_pre. lo_pre = lo_decorator. ENDIF. * Цепочка вызовов будет выглядеть так: alv output -> pdf output lo_decorator->process_output( ). ENDMETHOD. "run ENDCLASS. "mainapp IMPLEMENTATION PARAMETERS: p_pdf AS CHECKBOX. START-OF-SELECTION. mainapp=>run( iv_pdf = p_pdf ). |