程序基本设计中,可以犯的最大错误,就是丢弃用户输入的数据。
这看起来似乎不可能,怎么会有人这么干呢?可是,看看这个常见场景:
我们让用户输入自己的年龄。当然在数据库中设计一个年龄
字段。看起来很普通,是吗?但如果你没有同时在这条记录中加上一个输入日期
字段,你实际上就丢失了信息。当然,更好的输入设计是让用户输入出生日期。之所以如此,是因为年龄
不是一个基本事实信息,它不过是出生日期这个基本事实的递延数据。
在我正在重构的一个限量销售的系统中,需要统计用户的购买次数,保证一个用户每天只能买2次,每天只能买100元以下的总额。程序员设计时这个限量系统时立刻设计了两个计数器:购买次数
和购买总金额
,他没有犯刚才那个错误,同时也记下来了购买日期
,这些内容都存进了数据库。每次用户购买时对这两个计数器递增即可。很完美,很高效,是吗?
不幸的是,需求总是比你想象得更加怪异,很快客户需要限制某种特别的产品的购买次数。而我们的两个计数器却找不到这个信息!程序员又增加了第三个计数器x 特别产品购买次数
。为了支持这个计数器,他必须对过去递增计数器的地方加上新的处理代码。可以想象,程序很快变得非常难看,到处出现x 特别产品
。
为什么会出现这样的麻烦?是由于需求作怪吗?至少在这个场景上,问题就出现在开始的计数器设计上。当我们保存计数器而不是更基础的订单信息如产品号
、购买数量
的时候,我们就丢失了这些基本信息,而只保存了一些派生信息。我们可以很容易看到:实际上我们的计数器是很容易重新从基本订单信息中计算出来的,但反过来,基本订单却无法从计数器中算出来,即使加上第三个、第四个计数器也不行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。