【问题标题】:DDD Value Object equality, == vs .Equals()DDD 值对象相等,== vs .Equals()
【发布时间】:2013-01-24 17:12:19
【问题描述】:

所以我有一个值object,(随意说钱),我想为它实现平等。我知道 ==.Equals() 的预期/默认行为(引用和数据相等)。

不过,在这种情况下,我希望能够比较两个对象,并说它们在计算上是等价的(例如 1m 和 3 ft 是等价的) 但是对于持久性(使用NHibernate,我认为isDirty 取决于平等)、用户显示和货币选择,我希望它们被认为是不同的。

我应该,在这种情况下,

  1. ==.Equals() 有不同的行为(应该做什么),
  2. 无论我想在哪里检查等效性,只需检查每个属性(意味着额外的代码)
  3. 实现类似.IsEquivalent() 的方法(我不喜欢后者)
  4. 我缺少的其他东西

是否有我应该遵循的最佳实践/模式? 谢谢

编辑: 我收到了一些关于汇率变化的回复。为了清楚起见,所以更新。让我们说高度,而不是货币

  • 我想澄清一些假设:
  • //忽略:值对象包含十进制金额,字符串/类货币
  • //忽略:汇率不变。
  • // 忽略:类货币知道其与其他货币的汇率
  • 值对象包含十进制数量,字符串/类单位
  • 类单元知道它与另一个单元之间的转换
  • 我不打算扩大费率/转化率等

我更关心实践和模式,而不是实施货币。 基本上,同样的方法来处理一个人的身高,其中身高是一个值对象,({1,m} 到 {3,ft},其中 1m 始终“等于”/“等于”到 3ft)

【问题讨论】:

  • 使用 3) 它比 1) 干净得多。您还需要传入一个表示不同货币兑换价格的对象,因此这甚至不适合 ==Equals 的方法签名。

标签: c# nhibernate domain-driven-design equality value-objects


【解决方案1】:

我不会将 1.0 美元视为等于到 0.63 英镑。为了检查货币价值是否相等,您需要的信息不仅仅是两个值 - 您还需要当前汇率等。尤其如此,因为相同的两个值不会始终相等,如果两个值永远相等,则相等应该始终为真。

因此,AreEquivalentMonitaryValues() 之类的方法似乎是合适的 - 特别是考虑到需要额外的信息。

【讨论】:

  • 其实值对象是{1,USD}和{0.63,GBP}
  • @DawoodMoazzem 这两个不相等 - 虽然它们可能(此时)在某些方法中等同于相同的值,但平等应该是一种构造,以便相等的值总是相等的。
  • 我明白了。怎么说不是货币,而是身高。其中 1m 始终 = 3ft
  • @DawoodMoazzem 我仍然会通过方法或特定比较器将其视为相等(尽管 1m != 3ft :)) - 如果度量单位实际上是值的一部分,我不会将它们视为平等,因为平等表明您可以将它们互换没有影响,在这种情况下,影响是您将失去度量单位。
  • 1m != 3ft。你是对的,我懒得检查。因此,如果我希望在某些情况下不产生影响,但在其他情况下产生影响,我应该坚持使用 equals 检查所有属性,对于应该检查等价性的情况:有一个 IsEquivalent 方法吗?谢谢!
【解决方案2】:

由于您需要不同的相等定义,具体取决于您希望使用IEqualityComparer 的上下文。

由于类型本身的Reed suggests 相等实际上应该意味着“永远永远相等”而不是当前汇率相等,但是拥有 IEqualityComparer 只是意味着“从这个比较器的角度来看,他们是平等的”。从那里你可以让你的ExchangeRate 类型,或给定汇率的东西,能够创建一个IEqualityComparer<Money> 对象,该对象代表给定汇率的相等性。然后可以使用该相等比较器来比较各种类型的货币是否相等。

另一种方法完全是创建一种“不变货币”,并为您的班级提供ToInvariantFromInvariant 方法,以便非不变货币不相等(永远)并且不变货币可以相等,尽管货币生成不变值。

【讨论】:

  • 作为替代方案,如何为包含所需汇率的对象定义一个包装类?如果一个人有一个不可变的“汇率快照”类,该类使用工厂方法来包装包含货币的对象,则可以重载运算符以处理匹配的包装器(尝试在两个包装器上使用例如“+”或“
【解决方案3】:

创建一个类MoneyExchangeRates,它有一个方法IsWorthApproximatelyTheSame(Money m1, Money m2)

汇率会随着时间而变化,不要让它们成为全局可变状态。

【讨论】:

    猜你喜欢
    • 2019-06-12
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 2012-08-24
    • 2010-10-31
    • 2014-06-03
    • 2020-02-12
    • 1970-01-01
    相关资源
    最近更新 更多