
- •Гагарина. Л.Г., Федоров а.Р., Федоров п.А. Введение в архитектуру проектирования программного обеспечения Москва
- •Оглавление
- •5.11. Паттерны grasp
- •Глава 1. Архитектура как форма концептуального существования по
- •1.1. Определения архитектуры по и ее значимость
- •1.2. Место архитектурных решений
- •1.3. Роль архитектурных решений
- •1.4. Архитектурные концептуальные схемы. Определение и ретроспектива
- •Глава 2. Нормативные практики архитектурного описания по
- •2.1. Основные понятия
- •2.2. Содержание стандарта
- •2.3. Представления схемы ieee-1471
- •Глава 3. Рациональный процесс архитектурного моделирования
- •3.1. Архитектурные парадигмы
- •3.2. Примеры архитектурных стилей и моделей
- •Глава 4. Сравнительное сопоставление архитектурных видов
- •4.1. Сопоставление систем видов
- •4.2. Примеры систем видов
- •Языки описания архитектуры
- •Глава 5. Проектирование с учетом будущих изменений.
- •5.1. Что такое паттерн проектирования.
- •5.2. Как решать задачи проектирования с помощью паттернов
- •3. Зависимость от аппаратной и программной платформ.
- •5.4. Порождающие паттерны
- •5.4.1. Паттерн Фабричный метод (Factory Method) - уровень класса
- •Классический вариант фабричного метода, когда интерфейс фабричных методов объявляется в независимом классе-фабрике, а их реализация определяется конкретными подклассами этого класса (Рис. 33).
- •Реализация паттерна Factory Method на основе обобщенного конструктора
- •Void info() {
- •Void info() {
- •Void info() {
- •Int main()
- •V.Push_back( Warrior::createWarrior( Infantryman_id));
- •V.Push_back( Warrior::createWarrior( Archer_id));
- •V.Push_back( Warrior::createWarrior( Horseman_id));
- •Void info() {
- •Void info() {
- •Void info() {
- •Int main()
- •5.4.2. Паттерн Одиночка (Singleton) - уровень объекта
- •Классическая реализация Singleton
- •If(!p_instance)
- •Singleton Мэйерса
- •Улучшенная версия классической реализации Singleton
- •Void initialize( Singleton* p );
- •Void SingletonDestroyer::initialize( Singleton* p ) {
- •If(!p_instance) {
- •Использование нескольких взаимозависимых одиночек
- •Int main()
- •5.4.3. Паттерн Абстрактная фабрика (Abstract Factory) - уровень объекта
- •Пример кода для паттерна Abstract Factory
- •Void info() {
- •Int main()
- •5.4.4. Паттерн Строитель (Builder) - уровень объекта
- •Void info() {
- •Int main()
- •Infantryman
- •Infantryman
- •5.4.5. Паттерн Прототип (Prototype) - уровень объекта
- •Void info() {
- •Void info() {
- •5.4.6. Обсуждение порождающих паттернов
- •5.5. Структурные паттерны
- •5.5.1. Паттерн Адаптер, обертка (Adapter, wrapper)
- •Адаптер объекта применяет композицию объектов.
- •Int main()
- •Void adjust() {} // Настройка датчика (защищенный метод)
- •5.5.2. Паттерн Мост (Bridge)
- •Void log( string & str );
- •Достоинства паттерна Bridge
- •5.5.3. Паттерн компоновщик (Composite)
- •Описание паттерна Composite
- •Virtual void addUnit(Unit* p) {
- •Int main()
- •Virtual CompositeUnit* getComposite() {
- •Void addUnit(Unit* p);
- •Достоинства паттерна Composite
- •Недостатки паттерна Composite
- •5.5.4. Паттерн декоратор (Decorator , wrapper, обертка)
- •Реализация паттерна Decorator
- •Int width, height;
- •5.5.5. Паттерн фасад (Facade)
- •Void submitNetworkRequest()
- •If (_engineer.CheckOnStatus())
- •5.5.6. Паттерн приспособленец (Flyweight)
- •Структура паттерна приспособленец (Flyweight)
- •Icon(char *fileName)
- •Icon *FlyweightFactory::_icons[];
- •5.5.7 Паттерн заместитель (Proxy, surrogate, суррогат)
- •Void draw()
- •Int balance;
- •5.5.8. Обсуждение структурных паттернов
- •5.6. Паттерны поведения
- •5.6.1. ПаттернЦепочка обязанностей (Chain of Responsibility)
- •Void setNext(Base *n)
- •5.6.2. Паттерн Command (команда)
- •Реализация паттерна Command
- •5.6.3. Паттерн Interpreter (интерпетатор)
- •Совместное использование паттернов Interpreter и Template Method
- •Int interpret(char*); // interpret() for client
- •Virtual void interpret(char *input, int &total)
- •Int index;
- •If (!strncmp(input, nine(), 2))
- •Virtual char one(){}
- •Int items[10];
- •Int main()
- •5.6.5. Паттерн Mediator (посредник)
- •Virtual void changed();
- •Void Widget::changed()
- •Int main()
- •5.6.6. Паттерн Memento (хранитель)
- •Int _state;
- •Void static redo()
- •Int main()
- •Integer: 11
- •5.6.7. Паттерн Observer (наблюдатель)
- •Int value;
- •5.6.8. Паттерн State
- •Void setCurrent(State *s)
- •5.6.9. Паттерн Strategy
- •Void compress( const string & file ) {
- •5.6.10. Паттерн Template Method (шаблонный метод)
- •Void a()
- •V.Visit(this);
- •V.Visit(this);
- •V.Visit(this);
- •Int main()
- •5.6.12. Обсуждение паттернов поведения
- •5.7. Дальнейшее развитие идеи паттернов проектирования
- •5.8. Архитектурные системные паттерны
- •5.9. Паттерны управления
- •5.9.1. Паттерны централизованного управления
- •5.10. Паттерны интеграции корпоративных информационных систем
- •5.10.1. Структурные паттерны интеграции
- •5.10.2. Паттерны по методу интеграции
- •5.10.3. Паттерны интеграции по типу обмена данными
- •5.12. Антипаттерны (anti-patterns)
- •Глава 6. Архитектура и характеристики качества
- •6.1. Специфика требований к качеству по
- •6.2. Подход к построению архитектуры с позиций качества
- •6.3. Подходы к оцениванию архитектуры
5.6.3. Паттерн Interpreter (интерпетатор)
Название и классификация паттерна
Интерпретатор - паттерн поведения классов.
Назначение паттерна Interpreter
Для заданного языка определяет представление его грамматики, а также интерпретатор предложений этого языка.
Отображает проблемную область в язык, язык – в грамматику, а грамматику – в иерархии объектно-ориентированного проектирования.
Обсуждение паттерна Interpreter
Паттерн Interpreter определяет грамматику простого языка для проблемной области, представляет грамматические правила в виде языковых предложений и интерпретирует их для решения задачи. Для представления каждого грамматического правила паттерн Interpreter использует отдельный класс. А так как грамматика, как правило, имеет иерархическую структуру, то иерархия наследования классов хорошо подходит для ее описания.
Абстрактный базовый класс определяет метод interpret(), принимающий (в качестве аргумента) текущее состояние языкового потока. Каждый конкретный подкласс реализует метод interpret(), добавляя свой вклад в процесс решения проблемы.
Структура паттерна Interpreter
Паттерн Interpreter моделирует проблемную область с помощью рекурсивной грамматики. Каждое грамматическое правило может быть либо составным (правило ссылается на другие правила) либо терминальным (листовой узел в структуре ”дерево”).
Для рекурсивного обхода ”предложений” при их интерпретации используется паттерн Composite.
UML-диаграмма классов паттерна Interpreter
Участники
AbstractExpression - абстрактное выражение: объявляет абстрактную операцию Interpret, общую для всех узлов в абстрактном синтаксическом дереве;
TerminalExpression - терминальное выражение:
- реализует операцию Interpret для терминальных символов грамматики;
- необходим отдельный экземпляр для каждого терминального символа в предложении;
CompoundExpression- нетерминальное выражение:
- по одному такому классу требуется для каждого грамматического правила R :: = R1, R2... Rп;
- хранит переменные экземпляра типа AbstractExpression для каждого символа от Rl до Rп;
- реализует операцию Interpret для нетерминальных символов грамматики. Эта операция рекурсивно вызывает себя же для переменных, представляющихR1, R2... Rп;
Context - контекст: содержит информацию, глобальную по отношению к интерпретатору;
Client - клиент:
- строит (или получает в готовом виде) абстрактное синтаксическое дерево, представляющее отдельное предложение на языке с данной грамматикой. Дерево составлено из экземпляров классов CompoundExpression и TerminalExpression;
- вызывает операцию Interpret.
У паттерна интерпретатор есть следующие достоинства и недостатки:
грамматику легко изменять и расширять. Поскольку для представления грамматических правил в паттерне используются классы, то для изменения или расширения грамматики можно применять наследование. Существующие выражения можно модифицировать постепенно, а новые определять как вариации старых;
простая реализация грамматики. Реализации классов, описывающих узлы абстрактного синтаксического дерева, похожи. Такие классы легко кодировать, а зачастую их может автоматически сгенерировать компилятор или генератор синтаксических анализаторов;
сложные грамматики трудно сопровождать. В паттерне интерпретатор определяется по меньшей мере один класс для каждого правила грамматики (для правил, определенных с помощью формы Бэкуса-Наура - BNF, может понадобиться и более одного класса). Поэтому сопровождение грамматики с большим числом правил иногда оказывается трудной задачей. Но если грамматика очень сложна, лучше прибегнуть к другим методам, например воспользоваться генератором компиляторов или синтаксических анализаторов;
Пример паттерна Interpreter
Паттерн Intepreter определяет грамматическое представление для языка и интерпретатор для интерпретации грамматики. Музыканты являются примерами интерпретаторов. Тональность и продолжительность звуков могут быть описаны нотами. Такое представление является музыкальным языком. Музыканты, используя ноты, способны воспроизвести оригинальные частоту и длительность каждого представленного звука.
Использование паттерна Interpreter
Определите “малый“ язык, “инвестиции” в который будут оправданными.
Разработайте грамматику для языка.
Для каждого грамматического правила (продукции) создайте свой класс.
Полученный набор классов организуйте в структуру с помощью паттерна Composite.
В полученной иерархии классов определите метод interpret(Context).
Объект Context инкапсулирует информацию, глобальную по отношению к интерпретатору. Используется классами во время процесса ”интерпретации”.
Реализация паттерна Interpreter