260 likes | 413 Views
Design Patterns in C#. Interpreter Pattern. www.devbg.org/patterns course /. Васил Бакалов. mail[at]vassil.info Американски Университет в България http://www.aubg.bg/. Съдържание. Накратко за шаблона Проблем Структура на шаблона Примерна реализация Въпроси при реализацията
E N D
Design Patterns in C# Interpreter Pattern www.devbg.org/patternscourse/ Васил Бакалов mail[at]vassil.info Американски Университет в България http://www.aubg.bg/
Съдържание • Накратко за шаблона • Проблем • Структура на шаблона • Примерна реализация • Въпроси при реализацията • За и против шаблона • Упражнения
Накратко за шаблона • Схема, която решава различни задачи по тяхното описание • Създаване на : • език, чрез който се описва една задача • схемата за нейното решаване • Вместо решение на конкретен вариант на задачата, чрез описателен механизъм съставяме общо решение
Накратко за шаблона • Разпределение на задачата на съставящите я подзадачи • Дефинира се език, който описва всяка подобна задача. На този език съответстват класове, които извършват решаването на задачата.
Проблем Често срещан тип задача, на която е възможно да се състави общо решение Опростяване на логиката при извършване на задача с повтарящи се подзадачи
Структура на шаблона Граматиката на езика се изгражда въз основа на следните класове: AbstractExpression Декларира абстрактният метод Interpret, който е общ за всички възли в абстрактното синтактично дърво. TerminalExpression Имплементира действието на Interpret операцията за крайните символи в граматиката. Необходима е инстанция на такъв обект за всеки краен символ в изречението. NonterminalExpression Такъв клас е необходим за всяко едно правило R ::= R1 R2 ... Rn в граматиката. Съдържа инстанции от тип AbstractExpression за всеки от символите от R1 до Rn.
Структура на шаблона Имплементира операцията Interpret за не крайните символи в граматиката. Interpret обикновено се извиква рекурсивно за променливите представляващи символите R1 доRn. Context Съдържа информация глобална за интерпретатора. Client Построява (или приема) абстрактно синтактично дърво представляващо конкретно изречение в езика, дефиниран от граматиката.Абстрактното синтактично дърво се съставя от инстанции на NonterminalExpression и TerminalExpression класове.
Структура на шаблона Конкретните класове зависят от решавания проблем. Нека разгледаме конкретните класове в два примера Пример 1: Регулярни изрази Пример 2: Булева алгебра
Примерна реализация Регулярни изрази
Примерна реализация Идентифициране на обектите • Главен абстрактен клас, входна точка към задачата (в примера RegularExpression) Класове наследници, представляващи подклас задача (в примера LiteralExpression, AlternationExpression, SequenceExpression, и RepetitionExpression)
Примерна реализация raining & (dogs | cats) * raining dogs raining cats dogs raining catsand dogs It israining catsand dogs
Примерна реализация Пример 2: Булева Алгебра Пресмятане на стойността на булев израз. Поддръжка на: • Изрази (AND/ OR/ NOT) • Променливи • Константи
Примерна реализация Дефинициите на класовете: КласътBooleanExp: publicabstractclassBooleanExp { public BooleanExp(){} publicabstractbool Evaluate(Context aContext); publicabstractBooleanExp Replace(string name, BooleanExp bExp); publicabstractBooleanExp Copy(); }
Примерна реализация Класът VariableExpression: publicclassVariableExp : BooleanExp { public VariableExp(string name){mname = name;} publicoverridebool Evaluate(Context aContext) {return aContext.Lookup(this);} publicoverrideBooleanExp Replace(string name, BooleanExp bExp) { if (name.Equals(mname)) return bExp.Copy(); else returnnewVariableExp(mname); }
Примерна реализация publicoverrideBooleanExp Copy() { returnnewVariableExp(mname); } publicstring mname; } publicclassContext { Hashtable values; public Context() { values = newHashtable(); }
Примерна реализация publicbool Lookup(VariableExp varExp) { bool result = (bool)values[varExp.mname]; return result; } publicvoid Assign(VariableExp varExp, bool bval) { values.Add(varExp.mname, bval); } }
Демонстрация Булева алгебра, реализирана чрез шаблона Интерпретатор
Въпроси при реализацията Създаване на абстрактното синтактично дърво Разпознаването (парсване) не е дефинирано конкретно. Възможни са различни подходи, като табличен парсер или други (например рекурсивно спускане). Дефиниране на Interpret операцията Вместо всеки израз да имплементира Interpret операцията може да се използва шаблона Visitor. Решение ако се налага да ползваме различни интерпретатори. Споделяне на крайните символи чрез шаблона FlyWeight Граматики, чийто изречения съдържат множество срещания на даден краен символ, ще спечелят ако използват единствена инстанция на дадения символ.
За и против шаблона Предимства: • Граматиката се променя и разширява лесно Тъй като се използват класове, чрез наследяване лесно можем да променим или допълним граматиката • Подобност на класовете Класовете се имплементират по много сходен начин, което улеснява реализирането на шаблона и автоматизираното генериране на класове • Добавяне на нови начини за интерпретиране на изрази Лесно, чрез добавяне на нови операции на съществуващите класове
За и против шаблона Недостатъци: • Сложните граматики се поддържат трудно Тъй като за всяко правило в граматиката се дефинира поне един клас, при граматики с много правила броят на класовете се увеличава и кода става труден за поддръжка.
Interpreter Въпроси?
Упражнения • Да се напише програма, която чрез използване на шаблона Интерпретатор да изчислява десетичната стойност на дадено римско число
Използвана литература • Ерик Гама, Ричард Хелм, Ралф Джонсън, Джон Влисидес, Шаблони за дизайн, СофтПрес, 2005, ISBN 954-685-352-6