itmo_conspects

Лекция 8. Воркшоп 3

На этом воркшопе будут примеры использования структурных паттернов. Код воркшопа: https://github.com/is-oop-y27/workshop-3

Техническое задание: на основе модели создания статей из второго воркшопа сделать поддержку математических выражений.

Математические выражении могут содержать константы, переменные, бинарные операции (сложение, вычитание, умножение, деление), а также при данных значениях переменных уметь вычисляться.

Заметим, что любое выражение можно представить в виде бинарного дерева.

Сделаем в проекте второго воркшопа папку Expressions, где будет независимая от моделей статей реализация выражений. В ней создадим интерфейс IExpression с двумя методами:

Для вычисления выражения сделаем объект контекста, в котором будем производить вычисления. Контекст IExpressionEvaluationContext содержит в себе имена переменных и их значения. Внутри контекст вычисления выражения будет содержать словарь. У контекста сделаем метод, возвращающий резалт-тайп со значением переменной. Для него же сделаем билдер.

Операнды выражения в нашей модели являются либо константными значениями, либо переменными. Для констант сделаем класс ConstantExpression, реализующий IExpressionValue, наследующийся от IExpression. У константного значения сделаем свойство Value

Для VariableExpression, реализующий IExpression, сделаем метод Evalute, который достает значение из словаря контекста

Чтобы применять арифметические операторы к выражениям, сделаем BinaryOperatorExpression, принимающий два IExpression и IBinaryOperator. Реализации IBinaryOperator будут хранить в себе логику обработки двух выражений. По сути IBinaryOperator является поведенческим паттерном “Стратегия”. При вычислении BinaryOperatorExpression будет пытаться вычислить значения у своих детей; при успехе он применит операцию к полученным значениям.

Теперь сделаем Articles.Extensions для того, чтобы связать модели статей и матвыражений

Сделаем класс ExpressionRenderable - он будет мостом между интерфейсов IRenderable и IExpression. При вызове Render объект будет возвращать текстовое представление выражения.

Также сделаем декоратор StyledExpressionDecorator - он реализует интерфейс IExpression и содержит в себе модификатор для текста, при вызове метода Format он будет возвращать сформатированный текст. Аналогично сделам для интерфейса IExpressionValue