數量
使用數量及其單位表示有維度的值

2004 年 5 月 10 日
這是 進一步的企業應用程式架構開發 文章的一部分,我在 2000 年代中期撰寫。遺憾的是,從那時起,太多其他事情吸引了我的注意力,所以我沒有時間進一步研究它們,我也看不到在可預見的未來會有太多時間。因此,這些材料很大程度上仍處於草稿形式,在我找到時間再次研究它們之前,我不會進行任何更正或更新。
在許多情況下,我們希望電腦表示有維度的量:例如六英尺或三十公斤等值。通常這些表示為裸數字,主要是因為這是我們在語言提供的有限類型系統中所能做的最好的。
但是使用物件會促使我們在需要時新增新的基本類型,而為有維度的量指定一個特定類型會增加很多價值。當有維度的值是金錢時,這尤其正確。金錢是 數量 的特例,但也是最廣泛使用的特例,因為很多人願意花錢來看錢。
運作方式
數量 的基本概念是一個結合數量和單位的類別。在說數量是一個簡單的表示時。然而, 數量 真正有趣的地方在於你可以套用在上面的行為。
第一種行為是算術。你應該可以像加兩個數字一樣輕鬆地將兩個數量加在一起。此外,數量應該對加法和減法很敏感:至少可以防止你將 6 英尺加到 180 磅。
當您嘗試加入類似的單位(例如將 500 公尺加入 3 公里)時,加法會產生更複雜的問題。最簡單的方法是拒絕加法,強制客戶進行轉換。更精密的做法是查看您是否可以將一個參數轉換為另一個參數,如果可以,您就可以執行加法。您能做到多好取決於轉換器的精密程度。
乘法也有類似的精密變化。最簡單的方法是僅允許乘以和除以純量數字。更精密的做法是允許乘以其他數量,但接著您必須計算結果的單位。因此,如果您將 150 英里除以 2 小時,您會得到 75 英里/小時。
需要比較運算,以便您可以找出六英尺是否大於五英尺。這裡的問題與加法非常類似 - 您必須選擇要進行多少轉換。
提供一個簡單的介面以允許直接對數量進行轉換很有用,儘管轉換工作通常最好留給一個單獨的轉換器物件。但是,如果您只有少數幾個單位,則將它們直接嵌入數量類別會更容易。
您可以賦予數量最實用的行為之一,是提供列印和剖析方法,讓您可以輕鬆產生字串,並從字串產生數量。這個簡單的模式可以大幅簡化許多輸入和輸出行為,無論是對檔案或在 GUI 介面中。
對於簡單的列印,您可以有一個預設值,例如先列印金額,然後列印單位。當在某些情況下您想要在數字之前列印單位,而在其他情況下想要在數字之後列印單位時,就會中斷。通常這種變化會取決於單位,因此在這些情況下,您可以將列印和剖析行為放在單位上,並委派給它。
金錢
我在我使用的幾乎每個系統上都使用 數量,但我很少使用它來表示物理單位。我大部分時間都使用它來表示金錢。對於物理單位的許多註解都是相同的,但在使用金錢時,確實有其自己的旋轉需要記住。
最大的變更圍繞著轉換的整個區域。雖然物理單位的轉換形式不會隨著時間而改變,但金錢的匯率總是在變動。很明顯地,這會影響轉換運算,但這種影響也會波及加法、減法和比較運算。
當你轉換金錢時,至少需要提供某種時間參考,其粒度會依應用程式而定。但在許多情況下,你可能在不同的內容中進行個別轉換。
所有這些的結果是,你必須更小心處理算術或比較運算中金錢的自動轉換。因此,你經常會發現它們不被允許。
除了 數量 的功能之外,金錢的一個特別有用的功能是處理捨入。金錢通常以小數部分表示,但你永遠不應該使用實數來處理金錢。這樣做的原因是,實數的捨入行為幾乎從不符合金錢所需的條件,而忽略這一點很容易導致間歇性錯誤,這些錯誤在面額上很小,但卻令人沮喪。
然而,金錢物件可以編碼自己的捨入規則,這表示在你使用金錢時,大多數時候你不需要知道捨入規則。
與此相關的是棘手的除法問題。如果你將 100 美元除以 3,你會得到什麼?通常答案並不像 33.33 美元那麼簡單。問題在於,如果你將 33.33 美元相乘,你會得到 99.99 美元,這表示少了一分錢。會計師不喜歡一分錢不見了。因此,你必須找出適用於你所觀察情況的政策。通常的規則是,某人應該得到額外的一分錢,儘管是誰並不重要。因此,你可以在金錢物件中放置一個方法,以傳回你從除法中需要發放的金錢集合。
關聯式資料庫
關於 數量 的一個常見問題是如何將其用於關聯式資料庫和其他沒有能力建立新的輕量級類型的系統。你是否會在每個金錢值中儲存金額和貨幣代碼?
這裡的問題發生在有一個約束強制在特定內容中所有金錢都必須是相同貨幣時。因此,考慮你有一個具有許多分錄的帳戶。每個分錄都有金錢屬性來顯示分錄的金額,但帳戶上的所有分錄都具有相同的貨幣。將貨幣儲存在帳戶中一次,而不是在分錄中重複貨幣,這樣合理嗎?
我傾向於迴避這個問題,並留待您的資料庫設計的具體事項。我仍會敦促您在程式碼中使用金錢物件:由您決定如何將它們儲存在資料庫中。畢竟,資料庫不會從 數量 中為您提供任何行為優勢。您只能在程式碼中獲得這些優勢。
何時使用
正如您所收集的,我大量使用 數量,至少在金錢變異中。確實,在物件導向環境中,幾乎沒有理由不使用它。我經常注意到,人們害怕使用像這樣的小物件,主要是因為不熟悉。效能是一個經常被引用的問題,儘管我沒有看過或聽說過 數量 真的會成為效能問題。
有一個論點說,當只有一個單位時,使用 數量 是不值得的,因此當您只有一個貨幣時,不應該使用金錢。但是金錢的價值大部分來自於它的行為,而不是它的多單位能力,所以即使在這種情況下,我也會使用它。
進一步閱讀
在 P of EAA 中有更詳細地討論金錢變異