我已经在其他语言(以及Smalltalk原生语言)中添加了一些正则表达式引擎,它们似乎都有一个单独的“Lexer”或“Scanner”类.这让我感到困惑,因为我认为词法分析器是一个单独的函数,它应该将模式作为输入(可能是定义标记类型的“语法”对象),并返回标记流.我无法弄清楚接口将具有哪些额外功能,以及对象需要保持的额外状态.
如何将其分解为面向对象的设计?
我应该补充一点,当我阅读源代码时,我似乎看到了很多东西:一个在其名称的末尾添加了动词“er”的类.它似乎违背了“适当的面向对象设计”,即“清洁代码”和“代码完整”这样的书籍.
在思考面向对象时,我们试图在数据和行为之间建立明确的区别.对象具有两者,并且一般而言,数据的行为越独立越好.
这些基本的指导原则并不总是导致设计看起来很自然.原因是有时我们倾向于将与某些数据相关联的行为附加到相同的数据.这可能会隐藏应该拥有此类行为的实际对象.
这种现象的典型情况是算法.我们有一些数据:算法输入和一些行为:算法输出,并认为这种行为应该附加到数据.因此,我们努力将其作为所述数据的函数来实现.
然而,在大多数情况下,这种简单的方法是有问题的.例如,许多算法可能产生多个输出.以两个多项式的除法为例,其中输出是商和余数.即使算法产生单个输出,我们也可能会问它花了多长时间,甚至告诉它取消它的执行并停止自己等等.
由于这些原因(以及其他类型的原因),始终建议将算法视为对象而不是函数.这种对象的实例变量通常是指
inputs - "one or more depending on the algorithm" outputs - "idem" auxiliary - "for holding the algorithm internal state while running" progress - "for recording degree of advancement" state - "various uses"
将算法实现为对象将有助于添加以下功能:
>使用不同的输入重用相同的实例
>有一个举行输出的地方
>向用户提供反馈
>告诉算法取消并停止执行(通过将其状态设置为#cancel)
>计算迭代次数并注册其他内容以进行调试
如您所见,作为对象的算法比作为函数的算法更丰富.这并不意味着您将不得不辞职的功能方法.只需重新验证算法并让客户端对象提供一个函数,该函数将使用该算法并返回与该上下文相关的结果.