为什么Pharo定义算术+和 - 基本上是重复的代码?

nic*_*sor 5 math smalltalk pharo

我正在浏览Pharo的内部,并注意到算术+和 - 的定义看起来非常相似:

+ aNumber
"Refer to the comment in Number + "
aNumber isInteger ifTrue:
    [self negative == aNumber negative
        ifTrue: [^ (self digitAdd: aNumber) normalize]
        ifFalse: [^ self digitSubtract: aNumber]].
aNumber isFraction ifTrue:
    [^Fraction numerator: self * aNumber denominator + aNumber numerator denominator: aNumber denominator].
^ aNumber adaptToInteger: self andSend: #+
Run Code Online (Sandbox Code Playgroud)

- aNumber
"Refer to the comment in Number - "
aNumber isInteger ifTrue:
    [self negative == aNumber negative
        ifTrue: [^ self digitSubtract: aNumber]
        ifFalse: [^ (self digitAdd: aNumber) normalize]].
aNumber isFraction ifTrue:
    [^Fraction numerator: self * aNumber denominator - aNumber numerator denominator: aNumber denominator].
^ aNumber adaptToInteger: self andSend: #-
Run Code Online (Sandbox Code Playgroud)

正如我所看到的,这完全违背了设计事物的OO方式,而且通常很糟糕.为什么没有人找到更好的解决方案?

aka*_*ice 4

我能想到的最简单的事情是:

- aNumber
    ^self + aNumber negated
Run Code Online (Sandbox Code Playgroud)

然而,这会产生成本:

  • 创建另一个中间 LargeInteger 或 Fraction
  • 另外发送两条消息来执行 - 操作

我们在这里看到的是对优化的致敬。不要过早优化,这是广泛使用的低级操作。

这段代码还有一些不完美的地方:

  • isInteger 和 isFraction 的使用也可以替换为某种双重调度
  • 方法digitAdd:和digitSubtract:适用于存储为符号-幅度而不是2补码的整数,这是一个不完全明显的实现细节,值得评论-或者也许应该更好地重命名为digitAddMagnitude:digitSubtractMagnitude: