对“算术业务类型”(如金钱或时间)建模的最佳实践是什么?
是否建议使用显式加/乘操作来生成类?每种货币都应该有一个等级吗?
或者,不使用类型系统建模并将它们保持为BigDecimal更实用吗?
例如:企业有一个叫做“工作日”的概念(定义为8h)。
工作日可以加或减。工作日也可以乘以金钱。计算价格
我的第一个想法是拥有类WorkDay和Money。但考虑到算术运算,需要大量的“样板代码”。
发布于 2019-04-17 07:20:59
这个概念被称为“度量单位”(指的是罗伯特·哈维)。
伟大的博客文章:https://mikhail.io/2015/08/units-of-measurement-in-domain-design/
F#将其作为语言构造:
发布于 2019-04-15 02:31:38
或者,不使用类型系统建模并将它们保持为BigDecimal更实用吗?
这取决于:当有人试图向Money添加WorkDay时,您想要如何减少出现的错误?
在大多数情况下,您的计算根本不关心您的域模型。它只是查看寄存器、内存中的字节等等--完全不知道域。
代码服务器的设计可以帮助程序员避免错误。有时,这种帮助将是纯粹的语义标记,以防止程序员不小心不正确地应用领域概念。如果您有自动类型检查,那么有一类错误可以消除,您也可以利用类型系统为您管理某些域不变量。
我们希望减少错误,因为我们希望能够更准确地预测在代码中引入新特性的成本。
如果一切都是BigDecimal,那么泛型检查很难区分正确和不正确的代码,并且您会回到其他缓解策略(大量测试;乐观)。
每种货币都应该有一个等级吗?
那得看情况?货币在同一维度上确实是不同的单位,就像米和脚是不同的长度单位,或摄氏度和华氏度是不同的温度单位。将两者混淆在一起的Bugs可能非常糟糕;另一方面,行为并没有太大的变化,所以使用公共的Money属性和一些货币代码元数据可能比尝试为每个元数据管理不同的类型更实用。
发布于 2019-04-14 13:51:46
我几乎没有理由在我的商务课上实现算术运算。
商业规则往往相当简单,而不是新的数学形式。因此,在您的情况下,如果1+1“工作日”=2“工作日”,那么就不需要在BusinessDay类上实现+操作符,甚至可能根本不需要有一个工作日类!
此外,业务规则往往会改变,工作天数可能需要重新评估。这是很难的,如果你只有你的计算结果在当时。
也许你想要记录像“工作时间”这样的事实,然后对这些小时做一个计算,计算出多少个工作日。1+1个工作日可能实际上= 1.5
对金钱也是如此。
偶尔,你可以用新的类型和操作符来做一些非常优雅的事情,但是除非你的规则是一成不变的,除非你的优雅非常直观地使用它的艺术性而非实用性。
https://softwareengineering.stackexchange.com/questions/390338
复制相似问题