程序基本設計中,能夠犯的最大錯誤,就是丟棄用戶輸入的數據。程序員
這看起來彷佛不可能,怎麼會有人這麼幹呢?但是,看看這個常見場景:數據庫
咱們讓用戶輸入本身的年齡。固然在數據庫中設計一個年齡
字段。看起來很普通,是嗎?但若是你沒有同時在這條記錄中加上一個輸入日期
字段,你實際上就丟失了信息。固然,更好的輸入設計是讓用戶輸入出生日期。之因此如此,是由於年齡
不是一個基本事實信息,它不過是出生日期這個基本事實的遞延數據。設計
在我正在重構的一個限量銷售的系統中,須要統計用戶的購買次數,保證一個用戶天天只能買2次,天天只能買100元如下的總額。程序員設計時這個限量系統時馬上設計了兩個計數器:購買次數
和購買總金額
,他沒有犯剛纔那個錯誤,同時也記下來了購買日期
,這些內容都存進了數據庫。每次用戶購買時對這兩個計數器遞增便可。很完美,很高效,是嗎?code
不幸的是,需求老是比你想象得更加怪異,很快客戶須要限制某種特別的產品的購買次數。而咱們的兩個計數器卻找不到這個信息!程序員又增長了第三個計數器x 特別產品購買次數
。爲了支持這個計數器,他必須對過去遞增計數器的地方加上新的處理代碼。能夠想象,程序很快變得很是難看,處處出現x 特別產品
。產品
爲何會出現這樣的麻煩?是因爲需求做怪嗎?至少在這個場景上,問題就出如今開始的計數器設計上。當咱們保存計數器而不是更基礎的訂單信息如產品號
、購買數量
的時候,咱們就丟失了這些基本信息,而只保存了一些派生信息。咱們能夠很容易看到:實際上咱們的計數器是很容易從新從基本訂單信息中計算出來的,但反過來,基本訂單卻沒法從計數器中算出來,即便加上第三個、第四個計數器也不行。基礎