过度设计

荣耀 2002冬

大约三年前,我写了一个小程序,用于维护整个软件系统中所有诸如“性别”、“职务”之类的基础数据。这个程序使用了两个表,主要结构如下:

    CREATE TABLE TYPE
    (
      TYPE_ID        NUMBER ,
      TYPE_NAME      VARCHAR2(64),
      TYPE_CODE      CHAR(16),
      TYPE_VIEW      VARCHAR2(64) 
   
)

上面这个表用于管理所有基础数据类型,比如“性别”、“职务”等,下面的表则用于记录每一种类型可能取的值,比如对于“性别”来说,有“男”、“女”,而对于“职务”来说,会有“局长”、“小兵”等等。

    CREATE TABLE VALUE
    (
      VALUE_ID        NUMBER,
     
TYPE_ID         NUMBER,
      VALUE_NAME      VARCHAR2(64)
    )

每当用户创建一个类型时,程序同时就会在后台创建一个视图。创建视图的SQL语句大致如下(以“性别”为例):

CREATE OR REPLACE VIEW V_XB AS

SELECT VALUE_ID AS ID, VALUE_NAME AS NAME FROM VALUE WHERE TYPE_ID = (SELECT TYPE_ID FROM TYPE WHERE TYPE_CODE = 'XB')

这样一来,其它模块只要执行:

SELECT ID, NAME FROM V_XB

就可以使用“男、女”这些基础数据,换句话说,基础数据管理程序正是利用这些视图提供对外接口。

这个例子和“过度设计”有什么关系呢?问题出在上面SQL语句的WHERE子句上,本来这条SQL语句可以简化成这个样子:

CREATE OR REPLACE VIEW V_XB AS

SELECT VALUE_ID AS ID, VALUE_NAME AS NAME FROM VALUE WHERE TYPE_ID = 123(说明:123可以直接从程序中取到)

但我在设计时“聪明地预见到”,以后可能其它模块会使用这些TYPE_CODE直接到TYPE表中取数据。如此一来,TYPE_CODE就不可以为空,且值必须唯一。否则,根据TYPE_CODE取到的数据就可能有误。后来的事实证明,这个决定纯粹是一个自作聪明的“过度设计”,因为几乎没有任何人使用这个“高级”功能。

每当用户录入基本数据类型时,都要为类型额外添加一个编码,假如重复编码的话,还要弹出讨厌的出错信息。尽管用户早已习惯,有的用户甚至还能对这个本来失误的设计,帮我思考出一些“合理”的理由来,但我常常为这个“过度设计”内疚不已。

这个程序非常小,以至于用它来说明“过度设计”这个严肃的问题,似乎不够份量,小题大作。但我相信你可以很容易在你的周围发现更多、更严重的“过度设计”案例。

我们都要为“过度设计”付出代价。开发公司要投入更多的人力、物力和财力。用户要为可能永远都用不到的功能而浪费更多的金钱。从技术的角度来说,每增加一项功能,都要增加n行代码,而每增加n行代码,就等于增加了n/x个bug。但这都还不算最糟糕。

在强调“用户体验”的今天,“过度设计”的软件用户最为倒霉,他们不得不忍受因“过度设计”而导致的混乱、烦恼和恐惧。

你“过度设计”了吗?

-完-