简体   繁体   English

DDD值对象相等= = vs .Equals()

[英]DDD Value Object equality, == vs .Equals()

So I have a value object , (arbitrarily say money), and I want to implement equality for it. 因此,我有一个价值object ,(随意地说是金钱),我想为此实现平等。 I am aware of the intended/default behavior for == and .Equals() (reference and data equality). 我知道==.Equals()的预期/默认行为(引用和数据相等)。

In this case though, I want to be able to compare two objects, and say that they are equivalent for calculations (eg 1m and 3 ft are equivalent) however for persistence (using NHibernate , where isDirty I think depends on equality), user display and selection of currency, I want them to be considered different. 但是在这种情况下,我希望能够比较两个对象,并说它们对于计算是等效的(例如1m和3 ft等价),但是对于持久性而言(使用NHibernate ,我认为isDirty取决于相等性),用户显示和货币的选择,我希望它们被认为是不同的。

Should I, in this case, 在这种情况下,我应该

  1. Have different behavior for == and .Equals() (and which should do what), ==.Equals()行为不同(哪个应该做什么),
  2. Wherever I want to check equivalency, just check each property (means extra code) 我想检查等效性的地方,只需检查每个属性(意味着额外的代码)
  3. Implement a method like .IsEquivalent() (I'd prefer not to do the latter) 实现类似.IsEquivalent()的方法(我不希望后者不这样做)
  4. Something else that I'm missing 我想念的其他东西

Is there a best practice/pattern I should follow? 我应该遵循最佳实践/模式吗? Thanks 谢谢

Edit: i got some responses regarding changing exchange rates. 编辑:我得到了一些有关改变汇率的回应。 so updating for clarity. 因此,为了清楚起见进行更新。 lets say height, and not currency 让我们说高度,而不是货币

  • I'd like to clarify, some assumptions: 我想澄清一些假设:
  • // ignore: Value object contains decimal amount, string / class currency //忽略:值对象包含十进制数,字符串/类货币
  • // ignore: Exchange rates do not change. //忽略:汇率不变。
  • // ignore: the class currency is aware of its exhange rate to and from the other //忽略:类别货币知道其与另一货币之间的汇率变动
  • value object contains decimal qty, string / class unit 值对象包含十进制数量,字符串/类单位
  • the class unit is aware of its conversion to and from the other 班级单位知道自己与另一个单位之间的转换
  • i do not intend to expand rates / conversions etc 我无意扩大汇率/转化次数等

I'm more concerned about practices and patterns, as opposed to implementing currency. 我更关心实践和模式,而不是实施货币。 Basically, the same approach to a person's height, where height is a value object, ({1,m} to {3,ft}, where 1m is always "equal"/"equivalent" to 3ft) 基本上,对人的身高使用相同的方法,其中身高是一个值对象({1,m}至{3,ft},其中1m始终“等于” /“等于”至3ft)

I would not treat 1.0 USD as equal to 0.63 GBP. 我不会将1.0美元等于 0.63英镑。 In order to check for equality of monitary value, you'd need more information than just the two values - you'd also need the current exchange rate, etc. This is especially true, as the same two values won't be equal consistently , and equality should always be true if the two values are ever equal. 为了检查法定价值是否相等,您不仅需要两个值,还需要更多信息-您还需要当前汇率等。这尤其如此,因为相同的两个值不会始终相等 ,并且如果两个值相等,则相等应始终为true。

As such, a method, such as AreEquivalentMonitaryValues() , seems appropriate - especially given that extra info is required. 因此,诸如AreEquivalentMonitaryValues()类的方法似乎很合适-特别是在需要额外信息的情况下。

Since you want different definitions of equality depending on the context you'd want to use an IEqualityComparer . 由于根据上下文需要不同的相等性定义,因此需要使用IEqualityComparer

As Reed suggests equality for the type itself should really mean, "always and forever are equal" rather than equal for the current exchange rates, but having an IEqualityComparer just means that, "from the point of view of this comparer, they are equal". 正如里德(Reed)所建议的那样 ,类型本身的相等性实际上应表示“永远是永远相等的”,而不是当前汇率相等,但是拥有IEqualityComparer只是意味着“从比较器的角度来看,它们是相等的” 。 From there you can have your ExchangeRate type, or something that is given an exchange rate, be able to create an IEqualityComparer<Money> object that represents equality for a given exchange rate . 从那里,您可以拥有您的ExchangeRate类型,或者指定汇率的东西,可以创建一个IEqualityComparer<Money>对象,该对象表示给定汇率的相等性。 That equality comparer can then be used to compare various types of currencies for equality. 然后可以使用该平等比较器比较各种类型的货币是否平等。

Another approach entirely would be to create an "invariant currency", and give your class ToInvariant and FromInvariant methods so that non-invariant currencies are not equal (ever) and invariant currencies can be equal despite the currency that generated the invariant value. 另一种方法完全是创建“不变货币”,并为您的类提供ToInvariantFromInvariant方法,以使非不变货币不等于(曾经),尽管产生不变价值的货币也可以等于不变货币。

Create a class MoneyExchangeRates which has a method IsWorthApproximatelyTheSame(Money m1, Money m2) . 创建一个类MoneyExchangeRates ,该类具有方法IsWorthApproximatelyTheSame(Money m1, Money m2)

Exchange rates vary over time, don't make them global mutable state. 汇率会随时间变化,请不要使其成为全球可变状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM