1

我有一个与复合结构设计有关的问题。我有一个描述通用数学表达式的 Expression 抽象类。这个想法是一个表达式可以是一个原子表达式(如“x”或“3”)或某种原子表达式的聚合(如求和、乘积、求幂等)。事实证明,复合模式很好地描述了这一点,例如,Summatory 类继承自 OperationTerm,而后者又继承自 Expression,并包含 Expression 术语的“augends”列表。

一切都很好,直到我尝试在某些属性的基础上专门化其中一些表达式;例如,如果表达式由单项式项的求和组成,则应将其“标记”为多项式,以便以对客户端代码透明的方式优化某些类型的运算(如积分或导数) (应该只处理 Expression 对象)。

有人知道我如何设计这种结构(可能以可扩展的方式)吗?

4

4 回答 4

1

你不能。由于您希望拥有不同的专用表达式,因此您必须继承 Expression 类型。

通常,当您定义可用于构建这样的抽象语法树的类型时,您还提供了访问者和/或修饰符,客户端代码可以使用它来从根目录浏览/修改复合表达式。

至于构建一个新的复合表达式树,应该没有问题,因为客户端代码知道它想要组装什么样的表达式。

于 2009-06-11T12:46:17.373 回答
0

如果表达式是不变的,即它们在创建后永远不会被写入,那么您可以只创建专用类的实例(如果您想将细节保留在客户端代码之外,请使用工厂模式)。如果它们不是不变的,您可以使用State 模式,并将您谈论的“标签”视为表达式的不同状态。

于 2009-06-11T12:45:07.267 回答
0

如果CompositeExpression派生自Expression,并且Polynomial派生自CompositeExpression,那么Polynomial也是一个Expression(如您所说,对客户端代码透明)。

于 2009-06-11T12:47:04.563 回答
0

我认为你的做法是错误的。不要担心将事物标记为多项式等。

只要确保您从任何输入到实际数据结构的翻译都简单明了。

多项式之类的东西可以稍后添加或标记到您最初创建的通用结构中。

这种设计模式在计算机和自然语言的编译器/解释器中出现了很多。基本上,第一步是句法分析,在此您建立句法结构,例如句法树。然后是语义分析,将意义附加到句法上。从您的描述性术语来看,您可能正在为数学表达式实现解释器,所以这将是一个非常接近的匹配。

看看 Kernighan 和 Pike 的 dc(台式计算器)示例,Aho Hopcroft 和 Ullman 关于数据结构/语言解释器/编译器的书籍,一些现代简单编译器的示例等。它们也是设计模式的丰富资源(尽管它们早于该术语的流行)。

于 2009-06-11T13:18:15.190 回答