Метафора
Примером из жизни может служить способ сокращения набором слов определенных действий, например, говоря официанту в сабвее: «Серый, курица терияки, со всеми овощами, 1000 островов и чесночный», Вы тем самым даёте ему на интерпретацию некоторую команду, а он уже пытается её преобразовать в последовательность выполнения команд: достать и разрезать серый хлеб, положить куриную начинку со всеми овощами и залить это все двумя соусами, подать Вам.
Назначение
Паттерн Interpreter – позволяет сформировать объектно-ориентированное представление грамматики для заданного языка, а также описывает правила создания механизма интерпретации (толкования) предложений этого языка.
Диаграмма
На диаграмме определено некое абстрактное выражение, которое содержит один единственный метод interpret, наследники этого выражения делятся на две категории, терминальные выражения (те что не включают в себя другие) и не терминальные (внутри которых есть некоторое кол-во других выражений). Во время интерпретации обрабатывается некоторый контекст, используемый клиентом.
Пример
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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
* BNF: * * <sub> :== <bread> <ingredientList> <sauceList> * <bread> :== <whiteBread> <wheatBread> * <ingredientList> :== <tomatoIngredient> <chickenIngredient> * <sauceList> :== <garlicSauce> <cheeseSauce> CLASS lcl_context DEFINITION. PUBLIC SECTION. DATA: mv_output TYPE string. ENDCLASS. INTERFACE lif_expression. METHODS: interpret IMPORTING io_context TYPE REF TO lcl_context. ENDINTERFACE. *&---------------------------------------------------------------------* *& Соусы *&---------------------------------------------------------------------* CLASS lcl_garlicsauce DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. ENDCLASS. CLASS lcl_garlicsauce IMPLEMENTATION. METHOD lif_expression~interpret. io_context->mv_output = io_context->mv_output && `garlic sauce`. ENDMETHOD. ENDCLASS. CLASS lcl_cheesesauce DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. ENDCLASS. CLASS lcl_cheesesauce IMPLEMENTATION. METHOD lif_expression~interpret. io_context->mv_output = io_context->mv_output && `cheese sauce`. ENDMETHOD. ENDCLASS. CLASS lcl_saucelist DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. METHODS: add_sauce IMPORTING io_sauce TYPE REF TO lif_expression. PRIVATE SECTION. DATA: mt_sauces TYPE STANDARD TABLE OF REF TO lif_expression. ENDCLASS. CLASS lcl_saucelist IMPLEMENTATION. METHOD add_sauce. APPEND io_sauce TO mt_sauces. ENDMETHOD. METHOD lif_expression~interpret. DATA: lo_sauce TYPE REF TO lif_expression. io_context->mv_output = io_context->mv_output && `<--sauce list: `. LOOP AT mt_sauces INTO lo_sauce. lo_sauce->interpret( io_context ). io_context->mv_output = io_context->mv_output && ` `. ENDLOOP. io_context->mv_output = io_context->mv_output && `-->`. ENDMETHOD. ENDCLASS. *&---------------------------------------------------------------------* *& Ингридиенты *&---------------------------------------------------------------------* CLASS lcl_tomatoingredient DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. ENDCLASS. CLASS lcl_tomatoingredient IMPLEMENTATION. METHOD lif_expression~interpret. io_context->mv_output = io_context->mv_output && `tomato`. ENDMETHOD. ENDCLASS. CLASS lcl_chikeningredient DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. ENDCLASS. CLASS lcl_chikeningredient IMPLEMENTATION. METHOD lif_expression~interpret. io_context->mv_output = io_context->mv_output && `chiken`. ENDMETHOD. ENDCLASS. CLASS lcl_ingredientlist DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. METHODS: add_ingredient IMPORTING io_ingredient TYPE REF TO lif_expression. PRIVATE SECTION. DATA: mt_ingredients TYPE STANDARD TABLE OF REF TO lif_expression. ENDCLASS. CLASS lcl_ingredientlist IMPLEMENTATION. METHOD add_ingredient. APPEND io_ingredient TO mt_ingredients. ENDMETHOD. METHOD lif_expression~interpret. DATA: lo_ingredient TYPE REF TO lif_expression. io_context->mv_output = io_context->mv_output && `<--ingredient list: `. LOOP AT mt_ingredients INTO lo_ingredient. lo_ingredient->interpret( io_context ). io_context->mv_output = io_context->mv_output && ` `. ENDLOOP. io_context->mv_output = io_context->mv_output && `-->`. ENDMETHOD. ENDCLASS. *&---------------------------------------------------------------------* *& Хлеб *&---------------------------------------------------------------------* CLASS lcl_whitebread DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. ENDCLASS. CLASS lcl_whitebread IMPLEMENTATION. METHOD lif_expression~interpret. io_context->mv_output = io_context->mv_output && `<-- White bread -->`. ENDMETHOD. ENDCLASS. CLASS lcl_wheatbread DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. ENDCLASS. CLASS lcl_wheatbread IMPLEMENTATION. METHOD lif_expression~interpret. io_context->mv_output = io_context->mv_output && `<-- Wheat bread -->`. ENDMETHOD. ENDCLASS. *&---------------------------------------------------------------------* *& Саб *&---------------------------------------------------------------------* CLASS lcl_sub DEFINITION. PUBLIC SECTION. INTERFACES: lif_expression. METHODS: constructor IMPORTING io_saucelist TYPE REF TO lcl_saucelist io_bread TYPE REF TO lif_expression io_ingredientlist TYPE REF TO lcl_ingredientlist. PRIVATE SECTION. DATA: mo_saucelist TYPE REF TO lcl_saucelist, mo_bread TYPE REF TO lif_expression, mo_ingredientlist TYPE REF TO lcl_ingredientlist. ENDCLASS. CLASS lcl_sub IMPLEMENTATION. METHOD constructor. mo_saucelist = io_saucelist. mo_bread = io_bread. mo_ingredientlist = io_ingredientlist. ENDMETHOD. METHOD lif_expression~interpret. mo_bread->interpret( io_context ). mo_saucelist->lif_expression~interpret( io_context ). mo_ingredientlist->lif_expression~interpret( io_context ). ENDMETHOD. ENDCLASS. *&---------------------------------------------------------------------* *& Работа с шаблоном *&---------------------------------------------------------------------* START-OF-SELECTION. DATA(lo_saucelist) = NEW lcl_saucelist( ). lo_saucelist->add_sauce( io_sauce = NEW lcl_cheesesauce( ) ). lo_saucelist->add_sauce( io_sauce = NEW lcl_garlicsauce( ) ). DATA(lo_ingredientlist) = NEW lcl_ingredientlist( ). lo_ingredientlist->add_ingredient( io_ingredient = NEW lcl_chikeningredient( ) ). DATA(lo_sub) = NEW lcl_sub( io_bread = NEW lcl_whitebread( ) io_ingredientlist = lo_ingredientlist io_saucelist = lo_saucelist ). DATA(lo_context) = NEW lcl_context( ). lo_sub->lif_expression~interpret( lo_context ). WRITE lo_context->mv_output. |
Согласно представленной сверху BNF нотации наш объект SUB может интерпретировать свой состав в понятное человеку выражение (context).
Часто шаблон используется для построения DSL (предметно-ориентированных языков), пример на ABAP можно найти по ссылке.