Метафора
Хорошей метафорой будет башня управления в аэропорту, через неё пилоты запрашивают разрешение на посадку и взлёт, а уже диспетчер в ней решает кто, куда и в каком порядке будет приземляться и взлетать. Нет необходимости во взаимодействии пилотов друг с другом напрямую.
Назначение
Определяет объект, инкапсулирующий способ взаимодействия множества объектов друг с другом, тем самым, избавляя их от необходимости явно ссылаться друг на друга, уменьшая при этом сложность системы.
Каждая система, как правило, состоит из отдельных частей, которые решают свои конкретные задачи. Объединяя эти части где-нибудь в клиентском коде или какой-то отдельной сущности, мы создаём неявного посредника, в данном случае подсистемы не знают о том, кто их использует и какие еще есть подсистемы. Такое соединение подсистем можно обозначить как неявный посредник. В классическом же понимании из книги GoF, подсистемы знают о наличии посредника и о способе взаимодействия с подсистемами через посредника.
Диаграмма
Посредник (AbstractMediator) определяет интерфейс для обмена информацией между коллегами. Каждый коллега знает о своём посреднике и предоставляемом им интерфейсе коммуникации и использует его для связи с другими коллегами, не обращаясь к ним напрямую.
В случае, когда посредник один, смысла в наследовании наследника и выделения абстракции нет.
Пример
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 |
*&---------------------------------------------------------------------* *& Определение классов/интерфейсов *&---------------------------------------------------------------------* CLASS lcl_mediator DEFINITION DEFERRED. CLASS lcl_invoker DEFINITION. PUBLIC SECTION. METHODS: receive_message IMPORTING iv_message TYPE string iv_from TYPE string, constructor IMPORTING iv_name TYPE string io_mediator TYPE REF TO lcl_mediator, send_message IMPORTING iv_message TYPE string, get_name RETURNING VALUE(rv_name) TYPE string. PRIVATE SECTION. DATA: mv_name TYPE string, mo_mediator TYPE REF TO lcl_mediator. ENDCLASS. CLASS lcl_mediator DEFINITION. PUBLIC SECTION. METHODS: add_client IMPORTING io_client TYPE REF TO lcl_invoker, send_message IMPORTING iv_message TYPE string io_sender TYPE REF TO lcl_invoker. PRIVATE SECTION. DATA: mt_receivers TYPE TABLE OF REF TO lcl_invoker. ENDCLASS. *&---------------------------------------------------------------------* *& Реализация классов *&---------------------------------------------------------------------* CLASS lcl_mediator IMPLEMENTATION. METHOD add_client. APPEND io_client TO mt_receivers. ENDMETHOD. METHOD send_message. DATA: lo_receiver TYPE REF TO lcl_invoker. LOOP AT mt_receivers INTO lo_receiver WHERE table_line <> io_sender. lo_receiver->receive_message( iv_message = iv_message iv_from = io_sender->get_name( ) ). ENDLOOP. ENDMETHOD. ENDCLASS. CLASS lcl_invoker IMPLEMENTATION. METHOD constructor. mv_name = iv_name. mo_mediator = io_mediator. ENDMETHOD. METHOD receive_message. WRITE: mv_name, ` receive message:`, iv_message, ` from:`, iv_from. ENDMETHOD. METHOD send_message. mo_mediator->send_message( iv_message = iv_message io_sender = me ). ENDMETHOD. METHOD get_name. rv_name = mv_name. ENDMETHOD. ENDCLASS. *&---------------------------------------------------------------------* *& Работа с шаблоном *&---------------------------------------------------------------------* START-OF-SELECTION. DATA: lo_invoker1 TYPE REF TO lcl_invoker, lo_invoker2 TYPE REF TO lcl_invoker, lo_mediator TYPE REF TO lcl_mediator. CREATE OBJECT lo_mediator. CREATE OBJECT lo_invoker1 EXPORTING iv_name = 'John' io_mediator = lo_mediator. CREATE OBJECT lo_invoker2 EXPORTING iv_name = 'Mike' io_mediator = lo_mediator. lo_mediator->add_client( lo_invoker1 ). lo_mediator->add_client( lo_invoker2 ). lo_invoker1->send_message( 'Hi to all!' ). |
В примере реализовано что-то вроде чата, как видно дополнительных иерархий тут нет (для упрощения). Клиенты знают о наличии посредника и об интерфейсе взаимодействия через него.