Метафора
Стратегия используется для выбора различных путей достижения результата. Допустим, нам понадобилось сходить в магазин за продуктами, какой выбор у нас есть? Можно заказать продукты на дом, можно сходить самому, можно отправить жену :). В любом из возможных случаев вы получаете результат – продукты из магазина.
Назначение
Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Стратегия позволяет изменять алгоритмы независимо от клиентов, которые ими пользуются. Основная мотивация применения паттерна, возможность динамической подмены алгоритма во время исполнения.
Диаграмма
Context — это клиент стратегии. Интерфейс стратегии реализуют два класса, которые по-своему выполняют операцию execute. Паттерн не определяет правило определения той или иной стратегии. Стратегия может быть выбрана самим клиентом или внедрена извне. Так же паттерн не определяет, каким образом конкретные стратегии получат данные для своей работы. Количество операций так же не регламентируется.
Пример
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 |
PARAMETERS: p_a TYPE i, p_b TYPE i. PARAMETERS: p_mul TYPE abap_bool RADIOBUTTON GROUP 1, p_sum TYPE abap_bool RADIOBUTTON GROUP 1, p_sub TYPE abap_bool RADIOBUTTON GROUP 1. *&---------------------------------------------------------------------* *& Определение классов/интерфейсов *&---------------------------------------------------------------------* INTERFACE lif_strategy. METHODS: execute IMPORTING iv_a TYPE i iv_b TYPE i RETURNING VALUE(rv_result) TYPE i. ENDINTERFACE. CLASS lcl_strategy_multiply DEFINITION. PUBLIC SECTION. INTERFACES: lif_strategy. ALIASES: execute FOR lif_strategy~execute. ENDCLASS. CLASS lcl_strategy_sum DEFINITION. PUBLIC SECTION. INTERFACES: lif_strategy. ALIASES: execute FOR lif_strategy~execute. ENDCLASS. CLASS lcl_strategy_sub DEFINITION. PUBLIC SECTION. INTERFACES: lif_strategy. ALIASES: execute FOR lif_strategy~execute. ENDCLASS. *&---------------------------------------------------------------------* *& Реализация классов *&---------------------------------------------------------------------* CLASS lcl_strategy_multiply IMPLEMENTATION. METHOD execute. rv_result = iv_a * iv_b. ENDMETHOD. ENDCLASS. CLASS lcl_strategy_sum IMPLEMENTATION. METHOD execute. rv_result = iv_a + iv_b. ENDMETHOD. ENDCLASS. CLASS lcl_strategy_sub IMPLEMENTATION. METHOD execute. rv_result = iv_a - iv_b. ENDMETHOD. ENDCLASS. *&---------------------------------------------------------------------* *& Работа со стратегией: *&---------------------------------------------------------------------* START-OF-SELECTION. DATA: lif_strategy TYPE REF TO lif_strategy, lv_result TYPE i. CASE abap_true. WHEN p_mul. CREATE OBJECT lif_strategy TYPE lcl_strategy_multiply. WHEN p_sub. CREATE OBJECT lif_strategy TYPE lcl_strategy_sub. WHEN p_sum. CREATE OBJECT lif_strategy TYPE lcl_strategy_sum. ENDCASE. lv_result = lif_strategy->execute( iv_a = p_a iv_b = p_b ). WRITE lv_result. |
В примере в качестве контекста выступает сама программа, так же в рамках неё происходит определение того, какая стратегия расчёта нужна (умножение, вычитание, сложение).