为什么 class Money 通过示例扩展 Kent Beck 的 TDD 中的表达式?
Why does class Money extend Expression in Kent Beck's TDD by Example?
我正在学习 TDD by Example 到目前为止,我发现它是一本很棒的书。但有一点他告诉我们要写:
// in class Money:
Expression plus(Money addend) {
return new Money(amount + addend.amount, currency);
}
除非我们声明,否则不会构建:
class Money implements Expression {...
这对我来说真的没有意义。作者创建 Expression
作为 Sum
的接口,而 Money
与 Sum
没有任何共同之处。后来他为两个 classes 添加了共同的方法 reduce()
,但仅减少了 Money returns this
.
使 Money
实现 Expression
只是从 plus()
方法中删除错误的最省力的途径,但它用不必要的信息填充代码(它必须由于这个决定而实施 reduce())并增加熵。
我还没有考虑太多,但是做这样的事情不是更干净吗?
class Money {
Money plus(Money addend) {
return new Money(amount + addend.amount, currency).reduce();
}
}
// edited this, it previously returned Expression
编辑:
在下一章中,作者在另一个 class(名为 Bank
)中实现了一个 reduce()
方法,该方法在货币之间转换 Money
。我仍然觉得这是一个奇怪的解决方案,Sum
和 Expression
名称暗示我们应该为这个任务使用一个转换表达式 class。作者可能打算做的是使用递归来添加不同货币的钱。无论哪种方式,在我看来他都做了一些超前的计划,这似乎与书中介绍的 TDD 不兼容。
关于未雨绸缪
TDD 并不禁止提前计划。这个过程是关于获得对你的计划的快速反馈,而不是浪费数天(或数周)来制定精心设计的计划,只是为了看到它们 'not survive contact with reality'(用 Helmuth von Moltke 的话说)。提前考虑就好了。
不过,Kent Beck 在第 17 章中透露这不是他的第一个牛仔竞技表演:
"I have programmed money in production at least three times that I can think of. I have used it as an example in print another half-dozen times. I have programmed it live on stage [...] another fifteen times. I coded another three or four times preparing for writing [...] Then, while I was writing this, I thought of using expression as a metaphor and the design went in a completely different direction than before."
所以,如果您认为他在作弊:是的,他是。不过,他对此持开放态度。我认为动机是提出一个令人信服的例子。他还写道,这部分是基于对该书的早期评论。
在API
这并不能解释为什么代码看起来像这样,但这是有原因的。这实际上是一个不错的 API.
为什么你不能写类似 return new Expression(amount + addend.amount, currency).reduce()
的东西?
你不能,因为 reduce
方法不是无效的。它需要争论。您必须同时提供银行(持有货币兑换率)和目标货币。
记住代码解决的问题。人们总是弄错这个,我认为 Kent Beck(无意中)通过命名示例 Money.
加剧了混乱
问题不在于对金钱建模,而是对不同货币的投资投资组合建模。如果您有 25.000 美元和 10.000 瑞士法郎的投资组合,将其简化为单一货币会隐藏重要细节。通过多种货币的投资组合,您可以分散风险。投资组合所有者将希望看到其投资组合的不止一种视图。有时,他们希望看到按货币分组的投资组合,而在其他时候,他们希望看到 'the current total worth' 的投资组合以单一货币显示。
书中的API两种观点都可以。
底层 'metaphor' 被称为 表达式 的原因是 API 只是一个专门的表达式树。不过,结果相当不错,因为它是合法的。限于书中介绍的子类型,it informally gives rise to a monoid.
我正在学习 TDD by Example 到目前为止,我发现它是一本很棒的书。但有一点他告诉我们要写:
// in class Money:
Expression plus(Money addend) {
return new Money(amount + addend.amount, currency);
}
除非我们声明,否则不会构建:
class Money implements Expression {...
这对我来说真的没有意义。作者创建 Expression
作为 Sum
的接口,而 Money
与 Sum
没有任何共同之处。后来他为两个 classes 添加了共同的方法 reduce()
,但仅减少了 Money returns this
.
使 Money
实现 Expression
只是从 plus()
方法中删除错误的最省力的途径,但它用不必要的信息填充代码(它必须由于这个决定而实施 reduce())并增加熵。
我还没有考虑太多,但是做这样的事情不是更干净吗?
class Money {
Money plus(Money addend) {
return new Money(amount + addend.amount, currency).reduce();
}
}
// edited this, it previously returned Expression
编辑:
在下一章中,作者在另一个 class(名为 Bank
)中实现了一个 reduce()
方法,该方法在货币之间转换 Money
。我仍然觉得这是一个奇怪的解决方案,Sum
和 Expression
名称暗示我们应该为这个任务使用一个转换表达式 class。作者可能打算做的是使用递归来添加不同货币的钱。无论哪种方式,在我看来他都做了一些超前的计划,这似乎与书中介绍的 TDD 不兼容。
关于未雨绸缪
TDD 并不禁止提前计划。这个过程是关于获得对你的计划的快速反馈,而不是浪费数天(或数周)来制定精心设计的计划,只是为了看到它们 'not survive contact with reality'(用 Helmuth von Moltke 的话说)。提前考虑就好了。
不过,Kent Beck 在第 17 章中透露这不是他的第一个牛仔竞技表演:
"I have programmed money in production at least three times that I can think of. I have used it as an example in print another half-dozen times. I have programmed it live on stage [...] another fifteen times. I coded another three or four times preparing for writing [...] Then, while I was writing this, I thought of using expression as a metaphor and the design went in a completely different direction than before."
所以,如果您认为他在作弊:是的,他是。不过,他对此持开放态度。我认为动机是提出一个令人信服的例子。他还写道,这部分是基于对该书的早期评论。
在API
这并不能解释为什么代码看起来像这样,但这是有原因的。这实际上是一个不错的 API.
为什么你不能写类似 return new Expression(amount + addend.amount, currency).reduce()
的东西?
你不能,因为 reduce
方法不是无效的。它需要争论。您必须同时提供银行(持有货币兑换率)和目标货币。
记住代码解决的问题。人们总是弄错这个,我认为 Kent Beck(无意中)通过命名示例 Money.
加剧了混乱问题不在于对金钱建模,而是对不同货币的投资投资组合建模。如果您有 25.000 美元和 10.000 瑞士法郎的投资组合,将其简化为单一货币会隐藏重要细节。通过多种货币的投资组合,您可以分散风险。投资组合所有者将希望看到其投资组合的不止一种视图。有时,他们希望看到按货币分组的投资组合,而在其他时候,他们希望看到 'the current total worth' 的投资组合以单一货币显示。
书中的API两种观点都可以。
底层 'metaphor' 被称为 表达式 的原因是 API 只是一个专门的表达式树。不过,结果相当不错,因为它是合法的。限于书中介绍的子类型,it informally gives rise to a monoid.