我把这句话和很多软件方面的专家,系统方面的牛人还有软件开发的经理确认过,几乎所有的人都不约而同的认同这个说法。这句话听起来似乎有道理。如果上层是这样设计的,那么下层就要满足这些设计,这样这些上层的设计就成了下层的需求。
然而我认为,这是个致命的错误。
“为领导服务还是为人民服务?”
Requirement和Design是软件开发的两个维度,Design用来承载Requirement的实现。就像体积和重量一样,两者不能互相转换,设计也不能变成需求。需求经过分析,可以被细化,分解。并且需求分析也可以有很多选择。但无论如何细化,如何分解,其结果还是需求。同样的,设计也有高层架构和底层实现,也有很多可选的方案。但不论是多么高层次的设计,它总还是于设计,成不了需求。
之所以说这是个致命的错误,是因为正是因为这个错误的理念,软件的设计者在不断的人为创造“需求”。架构的设计者做了大量的BDUF(Big Design Up-Front,预先的大量设计),然后把它们交给下面的工程师当做需求去实现。这时大部分的工程师工作的目的已经不再是满足客户需求了,而是满足这些人为创造的所谓“需求”。这样一来,一方面,产生了大量无用的代码及其相关工作;另一方面,如此设计并不一定能满足最终需求,往往要等到最后的集成测试才突然发现其实设计没有满足需求,这时往往已经大势晚矣。
在我们动手设计之前,需求分析应该已经完成了,否则设计什么东西?当然,除非是为了设计而设计。在迭代开发的模式下,在进入每一个迭代之前,需求一定已经是清楚的,并且在这一个迭代中要花时间为今后的迭代进行需求分析。现在流行的描述需求的方法是用user story,它有这样的格式:
做为<某用户角色>,我需要<某功能>,因为<某原因>。
这样,需求就明显的和设计区分开了。
设计应该是“进化”式的,随着需求不断的被实现,系统的架构与设计逐渐的浮现出来。而不是先有了架构再向里面加东西。软件设计和建筑设计不同,对于软件这样复杂而充满未知的系统,其设计只能是“长(grow)”出来的,而不是“计划(plan)”出来。
诚然,有时系统的设计会影响到需求的细分。举一个例子:一个软件需要从网络自动下载网页进行处理,这个需求比较大,需要把它分解开才能进行迭代开发。那么根据系统架构,可以把需求分解为,1.从模拟接口(stub)下载网页进行处理;2.从真正的网络下载网页进行处理。这样做的好处不单单是让需求变小了,可以分成两次做甚至由不同的team来做。并且,它解开了网页处理和网络之间的依赖关系,方便实现依赖倒置。
感谢Craig Larman的耐心指正,让我理清了对需求与设计的混乱概念。总之,需求就是需求,设计就是设计。