2013-01-24 36 views
1

所以我有一個值object,(任意說錢),我想實現它的平等。我知道==.Equals()(參考和數據相等)的預期/默認行爲。DDD值對象相等,== vs .Equals()

在這種情況下,雖然,我希望能夠比較兩個對象,並說他們是等價的計算(例如1M和3英尺是等同的) 然而,對於持久性(使用NHibernate,其中isDirty我覺得要看平等),用戶顯示和貨幣選擇,我希望他們被認爲是不同的。

我應該在這種情況下,

  1. 有不同的行爲==.Equals()(和應該做的事情),
  2. 無論我想檢查等價,只是檢查每個屬性(意味着額外的代碼)
  3. 實現像.IsEquivalent()的方法(我寧願不要做後者)
  4. 別的東西,我錯過

我應該遵循最佳做法/模式嗎? 謝謝

編輯: 我收到了一些有關匯率變化的回覆。爲了清晰起見進行更新讓說的高度,而不是貨幣

  • 我想澄清,一些假設:
  • //忽視:值對象包含小數量,串/班幣
  • //忽視:匯率做不變。
  • //忽略:類貨幣知道其exhange速率向和從其他
  • 值對象包含十進制數量,串/類單元
  • 類單元知道它的轉換,並從其他的
  • 我不打算擴大率/轉換等

我更關心的是實踐和模式,而不是實施貨幣。 基本上,對於一個人的身高來說,同樣的方法,其中身高是價值對象,({1,m}到{3,ft},其中1m總是「等於」/「相當於」3ft)

+0

跟3)它比1更乾淨)。您還需要傳入一個代表不同貨幣的交易價格的對象,所以這甚至不適合'=='或'Equals'的方法簽名。 – CodesInChaos

回答

5

I不會將1.0美元視爲等於至0.63英鎊。爲了檢查單值的平等性,您需要更多的信息而不僅僅是兩個值 - 您還需要當前的匯率,等等。尤其如此,因爲相同的兩個值將不相等始終如一,並且如果兩個值始終相等,則相等應始終爲真。

因此,一種方法,如AreEquivalentMonitaryValues(),似乎是適當的 - 尤其是考慮到需要額外的信息。

+0

實際上價值對象是{1,USD}和{0.63,GBP} –

+0

@DawoodMoazzem而這兩者不是**平等** - 儘管它們(在此時間點)在某些方法論上等同於相同的值,平等應該是一個結構,以便相等的價值總是平等的。 –

+1

我明白了。怎麼說不是貨幣,但高度。 1m總是= 3ft –

0

創建一個類MoneyExchangeRates它有一個方法IsWorthApproximatelyTheSame(Money m1, Money m2)

匯率隨時間而變化,不要讓它們成爲全局可變狀態。

2

由於您希望使用IEqualityComparer的不同定義取決於上下文。

作爲Reed suggests類型本身的平等應該真正意味着「永遠和永遠是平等的」,而不是當前匯率的平等,但擁有IEqualityComparer只是意味着「從這個比較器的角度來看,它們是平等的「。從那裏你可以有你的ExchangeRate類型,或者是給定匯率的東西,能夠創建一個IEqualityComparer<Money>對象,該對象對於給定的匯率代表等於。那麼這個平等比較器可以用來比較各種貨幣的平等性。

另一種方法完全是創建一個「不變的貨幣」,給你的類ToInvariantFromInvariant方法,使非不變貨幣是不相等的(曾經)和不變的貨幣可以儘管產生不變的貨幣等於值。

+0

作爲替代方案,如何爲包含所需匯率的對象定義包裝類?如果有一個帶有工廠方法的不可改變的「匯率快照」類來包裝含有貨幣的對象,那麼可以重載操作符來處理匹配的包裝器(試圖在兩個包裝器上使用「+」或「<」由同一工廠生成的異常會引發異常)。靜態確認操作只在兼容的包裝上執行可能會更清晰,但我不知道有任何這樣做的方法。 – supercat