Наследование в составной структуре - PullRequest
1 голос
/ 11 июня 2009

У меня проблема, связанная с проектированием композитной конструкции. У меня есть абстрактный класс Expression, который описывает общее математическое выражение. Идея заключается в том, что выражение может быть атомарным выражением (например, «x» или «3») или каким-то образом агрегированным атомарным выражением (например, сумматорами, производными, возведения в степень и т. Д.). Это хорошо описывается шаблоном Composite, поэтому, например, класс Summatory наследует от OperationTerm, который, в свою очередь, наследует от Expression и содержит список «augends» терминов Expression.

Все хорошо, пока я не попытаюсь специализировать некоторые из этих выражений на основе некоторых свойств; например, если выражение состоит из терминов Summatory of Monomial, его следует «пометить» как полином, чтобы оптимизировать определенные виды операций (например, интегралы или производные) таким образом, чтобы это было прозрачно для клиентского кода. (это должно обрабатывать только объекты Expression).

У кого-нибудь есть идеи о том, как я могу спроектировать такую ​​структуру (возможно, расширяемым образом)?

Ответы [ 4 ]

1 голос
/ 11 июня 2009

Вы не можете. Так как вы хотите иметь разные специализированные выражения, вам придется создавать подклассы Expression type.

Обычно, когда вы определяете типы, которые можно использовать для создания таких деревьев абстрактного синтаксиса, вы также предоставляете Visitor и / или модификатор, который клиентский код может использовать для просмотра / изменения составного выражения из корень.

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

0 голосов
/ 11 июня 2009

Я думаю, что вы делаете это неправильно. Не беспокойтесь о маркировке вещей как многочлена и т. Д.

Просто убедитесь, что ваш перевод из любого ввода в фактическую структуру данных прост и понятен.

Такие вещи, как полином, могут быть добавлены позже или помечены позже в общей структуре, которую вы создали изначально.

Этот тип шаблона проектирования часто встречается в компиляторах / интерпретаторах как для компьютерных, так и для естественных языков. По сути, первым шагом является синтаксический анализ, где вы создаете синтаксическую структуру, например, синтаксическое дерево. Затем, есть семантический анализ, где значение присоединяется к синтаксису. Судя по описательным терминам, вы, вероятно, используете интерпретатор математических выражений, так что это будет очень близкое совпадение.

Взгляните на Kernighan и Pike для их примера dc (настольного калькулятора), книг Aho Hopcroft и Ullman по структурам данных / интерпретаторам / компиляторам языка, примерам некоторых современных простых компиляторов и т. Д. Они являются плодотворным источником шаблонов проектирования, таких как: хорошо (хотя они предшествуют популярности термина).

0 голосов
/ 11 июня 2009

Если CompositeExpression получено из Expression, а Polynomial получено из CompositeExpression, то Polynomial также является Expression (как вы сказали, прозрачным для клиентского кода).

0 голосов
/ 11 июня 2009

Если выражения являются инвариантными, т.е. они никогда не записываются после создания, тогда вы можете просто создать экземпляры специализированного класса (используя шаблон Factory, если вы хотите сохранить детали в коде клиента). Если они не являются неизменными, вы можете использовать шаблон State и просто рассматривать «метки», о которых вы говорите, как различные состояния выражения.

...