Контекстний клас у шаблоні стратегії


10

Я намагаюся зрозуміти схему стратегії і запитую себе: чи повинен бути контекстний клас обов'язковим чи можна його залишити без шкоди для мети шаблону?

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

введіть тут опис зображення

Зображення, зняте з Вікімедії

Чи може клієнт делегувати безпосередньо інтерфейс стратегії чи щось я просто пропустив, щоб зрозуміти про контекстний клас?

interface Reader {
    // read information from file and fill data list field of Client
    readFile();
}
class ExcelReader implements Reader{ /* */ }
class PdfReader implements Reader{ /* */}

class Client{
    // strategic choice
    Reader r;

    // data list field
    List<Data> data;

    // Client Constructor
    public Client(){
        if(<file ends in .xls>)
            r = new ExcelReader();
        else
            r = new PdfReader();
        r.readFile();
    }
}

Отже, вище зображено відсутність контекстного класу. Чи дотримується код стратегії?


1
Як ще один цікавий / важливий момент я хотів би звернути вашу увагу, що концепція типів класів у функціональних мовах - це "просто" шаблон стратегії з видами en.wikipedia.org/wiki/Kind_(type_theory) ). Обидва є лише механізмом реалізації спеціального поліморфізму.
AndreasScheinert

Чи пов’язано це (далеко чи менше) з Java 8 Project Lambda? Стаття у Вікіпедії занадто щільна для мене, щоб просто зрозуміти її одразу, але якщо вони є частиною теоретичної основи для ефективного використання майбутніх функцій Java (або програмування взагалі), я із задоволенням вкладу в неї більше часу.
пані

1
Дуже далеко, але я заперечу, що так, потрібні класи типу. Мова програмування, що підтримує більш високі типи. Так би було у випадку з Скалою та Хаскеллом. Моя думка тут полягала в тому, що (ad hoc) поліморфізм реалізується по-різному, і якщо ви відступите, ви зможете дізнатися деякі уявлення про поліморфізм взагалі.
AndreasScheinert

Відповіді:


13

У вашому прикладі виклик коду readFileє частиною конструктора Client. Цей метод - це "контекст", який ви шукаєте . Шаблон стратегії не потребує "контекстного класу" буквально, і при першій версії коду об'єкт стратегії ("Читач" у вашому випадку) може міститись лише в локальній змінній. Особливо, коли існує лише один "стратегічний метод" ("readFile").

Однак, якщо ваша кодова база зростає від однієї версії до іншої, навряд чи можна отримати більше і більше "стратегічних" методів, і рішення, яку стратегію застосувати та виконання "стратегічних методів", буде відбуватися в різний час і в різних місцях вашого коду. Таким чином, ви починаєте рефакторировать їх, щоб зберегти логіку в одному місці. Це призведе прямо до реалізації, схожого на діаграму у вашому запитанні.


5

Звичайно. Візерунки - це лише настанови. Вам все одно потрібно буде адаптуватися та застосувати їх правильно для наявної проблеми. Особисто я рідко коли-небудь дозволяю встановлювати стратегію під час виконання; частіше її вказують на будівництві або на заводі.

Хоча можна також стверджувати, що setStrategyце приватне, і моя ін'єкція просто використовує схему, як показано на малюнку.


Чи означає це, що зображений клас контексту може залишатися без шкоди для шаблону? Або інакше кажучи, це нормально , коли мій клас клієнт є зображена контекст класу?
пані

6
@panny - Я вагаюся, щоб відповісти на питання, оскільки це вказує, що ви пропустили точку відповіді, та й взагалі шаблони. Шаблон стратегії дозволяє змінювати поведінку, надаючи різні конкретні реалізації за інтерфейсом. Це концепція , а не формула .
Теластин
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.