Метафора
Метафорой данного шаблона можно представить какой-нибудь орган гос. власти. Вы приходите в налоговую инспекцию за получением справки, оставляете заявление на её получение. Заявление у вас принимает один специалист, а далее в зависимости от типа документа, перенаправляет его на нужного человека, который специализируется обработкой этих заявок. Таким образом, ваше заявление (сообщение) проходит и обрабатывается в некоторой цепочке специалистов.
Назначение
Шаблон рекомендован для использования в условиях, когда:
- в разрабатываемой системе имеется группа объектов, которые могут обрабатывать сообщения определенного типа;
- все сообщения должны быть обработаны хотя бы одним объектом системы;
- сообщения в системе обрабатываются по схеме «обработай сам либо перешли другому», то есть одни сообщения обрабатываются на том уровне, где они получены, а другие пересылаются объектам иного уровня.
Диаграмма
Каждый конкретный обработчик знает о существовании следующего в цепочке обработки событий и если он сам не может обработать событие, тогда делает перенаправление на следующего обработчика.
Пример
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
*&---------------------------------------------------------------------* *& Определение классов *&---------------------------------------------------------------------* CLASS lcl_message_handler DEFINITION ABSTRACT. PUBLIC SECTION. TYPES: ty_priority TYPE i. CONSTANTS: gc_error_msg TYPE ty_priority VALUE 1, gc_warning_msg TYPE ty_priority VALUE 2, gc_notice_msg TYPE ty_priority VALUE 3. DATA: mv_mask TYPE ty_priority, mo_next TYPE REF TO lcl_message_handler. METHODS: constructor IMPORTING io_next TYPE REF TO lcl_message_handler OPTIONAL iv_mask TYPE ty_priority, write_message IMPORTING iv_message TYPE string iv_priority TYPE ty_priority. PROTECTED SECTION. METHODS: write_message_int ABSTRACT IMPORTING iv_message TYPE string. ENDCLASS. "lcl_message_handler DEFINITION CLASS lcl_write_handler DEFINITION INHERITING FROM lcl_message_handler. PROTECTED SECTION. METHODS: write_message_int REDEFINITION. ENDCLASS. "lcl_write_handler DEFINITION CLASS lcl_log_handler DEFINITION INHERITING FROM lcl_message_handler. PROTECTED SECTION. METHODS: write_message_int REDEFINITION. ENDCLASS. "lcl_log_handler DEFINITION CLASS lcl_email_handler DEFINITION INHERITING FROM lcl_message_handler. PROTECTED SECTION. METHODS: write_message_int REDEFINITION. ENDCLASS. "lcl_email_handler DEFINITION *&---------------------------------------------------------------------* *& Реализация классов *&---------------------------------------------------------------------* CLASS lcl_message_handler IMPLEMENTATION. METHOD constructor. mo_next = io_next. mv_mask = iv_mask. ENDMETHOD. "constructor METHOD write_message. IF iv_priority <= mv_mask. write_message_int( iv_message ). ENDIF. CHECK mo_next IS BOUND. mo_next->write_message( EXPORTING iv_message = iv_message iv_priority = iv_priority ). ENDMETHOD. "write_message ENDCLASS. "lcl_message_handler IMPLEMENTATION CLASS lcl_write_handler IMPLEMENTATION. METHOD write_message_int. WRITE / : `Write notice: `, iv_message. ENDMETHOD. "write_message_int ENDCLASS. "lcl_write_handler IMPLEMENTATION CLASS lcl_log_handler IMPLEMENTATION. METHOD write_message_int. WRITE / : `Write to log: `, iv_message. ENDMETHOD. "write_message_int ENDCLASS. "lcl_log_handler IMPLEMENTATION CLASS lcl_email_handler IMPLEMENTATION. METHOD write_message_int. WRITE / : `Send to email: `, iv_message. ENDMETHOD. "write_message_int ENDCLASS. "lcl_email_handler IMPLEMENTATION *&---------------------------------------------------------------------* *& Работа с шаблоном *&---------------------------------------------------------------------* START-OF-SELECTION. DATA: lo_write_handler TYPE REF TO lcl_write_handler, lo_log_handler TYPE REF TO lcl_log_handler, lo_email_handler TYPE REF TO lcl_email_handler. CREATE OBJECT lo_email_handler EXPORTING iv_mask = lcl_message_handler=>gc_error_msg. CREATE OBJECT lo_log_handler EXPORTING io_next = lo_email_handler iv_mask = lcl_message_handler=>gc_warning_msg. CREATE OBJECT lo_write_handler EXPORTING io_next = lo_log_handler iv_mask = lcl_message_handler=>gc_notice_msg. lo_write_handler->write_message( EXPORTING iv_message = 'Ошибка обрабатывается всеми обработчиками' iv_priority = lcl_message_handler=>gc_error_msg ). ULINE. lo_write_handler->write_message( EXPORTING iv_message = 'Ошибка обрабатывается только Write обработчиком' iv_priority = lcl_message_handler=>gc_notice_msg ). ULINE. lo_write_handler->write_message( EXPORTING iv_message = 'Ошибка обрабатывается только Write обработчиком и Log обработчиком' iv_priority = lcl_message_handler=>gc_warning_msg ). |
В примере выстроена цепочка обработчиков сообщения и в зависимости от приоритета сообщения обработка попадает на того или иного обработчика.
В данном случае только от Вас зависит, каким образом будет выстроена цепочка (следующий обработчик может быть передан в конструкторе или внедрен как зависимость во время исполнения).