Стратегія (шаблон проєктування)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Стратегія (англ. Strategy) — шаблон проєктування, належить до класу шаблонів поведінки. Відомий ще під іншою назвою — «Policy». Його суть полягає у тому, щоб створити декілька схем поведінки для одного об'єкту та винести в окремий клас. Шаблон Стратегія (Strategy) дозволяє міняти вибраний алгоритм незалежно від об'єктів-клієнтів, які його використовують.

Основні характеристики[ред. | ред. код]

Завдання[ред. | ред. код]

За типом клієнта (або за типом оброблюваних даних) вибрати відповідний алгоритм, який слід застосувати. Якщо використовується правило, яке не піддається змінам, немає необхідності звертатися до шаблону «стратегія».

Структура[ред. | ред. код]

Мотиви[ред. | ред. код]

  • Програма повинна забезпечувати різні варіанти алгоритму або поведінки
  • Потрібно змінювати поведінку кожного екземпляра класу
  • Необхідно змінювати поведінку об'єктів на стадії виконання
  • Введення інтерфейсу дозволяє класам-клієнтам нічого не знати про класи, що реалізують цей інтерфейс і інкапсулюють в собі конкретні алгоритми

Спосіб вирішення[ред. | ред. код]

Відділення процедури вибору алгоритму від його реалізації. Це дозволяє зробити вибір на підставі контексту.

Учасники[ред. | ред. код]

  • Клас Strategy визначає, як будуть використовуватися різні алгоритми.
  • Конкретні класи ConcreteStrategy реалізують ці різні алгоритми.
  • Клас Context використовує конкретні класи ConcreteStrategy за допомогою посилання на конкретний тип абстрактного класу Strategy. Класи Strategy і Context взаємодіють з метою реалізації обраного алгоритму (в деяких випадках класу Strategy потрібно надсилати запити класу Context). Клас Context пересилає класу Strategy запит, що надійшов від його класу-клієнта.

Наслідки[ред. | ред. код]

  • Шаблон Strategy визначає сімейство алгоритмів.
  • Це дозволяє відмовитися від використання перемикачів і / або умовних операторів.
  • Виклик всіх алгоритмів повинен здійснюватися стандартним чином (всі вони повинні мати однаковий інтерфейс).

Реалізація[ред. | ред. код]

Клас, який використовує алгоритм (Context), включає абстрактний клас (Strategy), що володіє абстрактним методом, визначальним спосіб виклику алгоритму. Кожен похідний клас реалізує один необхідний варіант алгоритму.

Використання[ред. | ред. код]

Архітектура Microsoft WDF заснована на цьому патерні. У кожного об'єкта «драйвер» і «пристрій» є незмінна частина, вшита в систему, в якій реєструється змінна частина (стратегія), написана в конкретній реалізації. Змінна частина може бути і зовсім порожньою, що означає, що драйвер нічого не робить, але при цьому здатний брати участь у PnP і управлінні живленням.

Бібліотека ATL містить у собі набір класів threading model, які є стратегіями (різними реалізаціями Lock / Unlock, які потім використовуються основними класами системи). При цьому в цих стратегіях використовується статичний поліморфізм через параметр шаблону, а не динамічний поліморфізм через віртуальні методи.

Призначення шаблону проєктування Стратегія[ред. | ред. код]

Існують системи, поведінка яких визначається відповідно до певного роду алгоритмів. Всі вони подібні між собою: призначені для вирішення спільних задач, мають однаковий інтерфейс для користування, але відрізняються тільки «поведінкою», тобто реалізацією. Користувач, налаштувавши програму на потрібний алгоритм — отримує потрібний результат.

Приклад. Є програма(інтерфейс) через яку обраховується ціна на товар для покупців у яких є знижка та ціна за сезонною знижкою — обираємо необхідний алгоритм. Об'єктно-орієнтований дизайн такої програми будується на ідеї використання поліморфізму. Результатом є набір «класів-родичів» — у яких єдиний інтерфейс та різна реалізація алгоритмів.
  • Недоліками такого алгоритму є те, що реалізація жорстко прив'язана до підкласу, що ускладнює внесення змін.
  • Вирішенням даної проблеми є використання патерну Стратегія (Strategy).

Переваги та недоліки[ред. | ред. код]

Переваги[ред. | ред. код]

  • Можливість позбутися умовних операторів.
  • Клієнт може вибирати найбільш влучну стратегію залежно від вимог щодо швидкодії і пам'яті.

Недоліки[ред. | ред. код]

  • Збільшення кількості об'єктів.
  • Клієнт має знати особливості реалізацій стратегій для вибору найбільш вдалої.

Зв'язок з іншими патернами[ред. | ред. код]

  • Стратегія змінює реалізацію, декоратор — доповнює
  • В стратегії користувач знає про класи стратегій і міняє їх самостійно, в стані різноманітні стани приховані від користувача, а за їх заміну відповідає сам клас
  • Міст — це структурний патерн. Його компоненти зазвичай встановлюються раз і не змінюються під час виконання програми. Використовують для розділення абстракції та реалізації. Стратегія — це шаблон поведінки. Використовують коли коли алгоритми можуть замінювати один одного під час виконання програми.
  • Шаблонний метод задає кроки алгоритму, які реалізовують підкласи. Стратегія задає алгоритм який можна виконати декількома способами, до того ж вибрати ці способи на етапі виконання програми

Приклади[ред. | ред. код]

Приклад на Java[ред. | ред. код]

Приклад на C++[ред. | ред. код]

Приклад на C #[ред. | ред. код]

Приклади на D[ред. | ред. код]

Приклад на Delphi[ред. | ред. код]

Приклади на Javascript[ред. | ред. код]

Приклад з використанням динамічних (first-class) функцій[ред. | ред. код]

Приклади на PHP5

Приклад на Python[ред. | ред. код]

Висновки[ред. | ред. код]

Останнім часом розроблено багато мов програмування, але в кожній з них для досягнення найкращого результату роботи необхідно використовувати шаблони програмування, одним з яких є Стратегія (Strategy).

Джерела[ред. | ред. код]

Design Patterns: Elements of Reusable Object-Oriented Software [Архівовано 9 листопада 2012 у Wayback Machine.]

Література[ред. | ред. код]

  • Bishop, Judith. C# 3.0 Design Patterns. Sebastopol, California: O'Reilly, 2008.
  • Tomas Petricek, Jon Skeet. Functional Programming for the Real World. б.м.: Manning Publications, 2010.

Посилання[ред. | ред. код]