# 五、轻松写就功能规格说明书 - 第1节:为什么烦心? 当约耳试验刚发表时,读者反映说执行上最困难的一点就是写规格.看起来规格 就像用牙线:大家都知道应该要,却没有人真的在做. 为什么大家不写规格呢?有人声称跳过写规格这个步骤可以节省时间.讲得好像 写规格像是什么奢侈品,只有NASA航天飞机工程师或为大保险公司工作的人才 能做.胡说八道.不写规格是软件项目中一个最大且不必要的风险.这就像只在背 上挂件衣服就妄想飞越摩哈维沙漠一样的愚意.那些不订规格直接写程序的程序 员和软件工程师都会自认是神枪手,可以朝背后开枪.才怪.他们根本没有生产力. 他们写出烂程序并做出低劣的产品,而且还让项目承受完全可以避免的极大风 险. 我认为所有重要的项目(写程序时间超过一周或一个以上的程序员)都一样,如 果没有规格,绝对会耗时更久并且写出质量低劣的程序.理由如下. 规格最重要的功能是要设计程序.即使你是自己一个人写好所有的程序,而且 写了规格也只是自己在看,写规格这个动作(详细描述程序运作)还是能迫使你 实际设计程序. 让我们看看分属两家公司的两名虚构程序员.快餐香蕉软件的史快手从来不写 规格规格?我们才不要讨厌的规格!”而好脾气软件公司的罗杰先生则在规格 确定前绝对不写程序.他们只是我众多虚构朋友中的两位. 史快手和罗杰先生有个相同点:他们都负责自家产品2.0版的向后兼容事宜. 史快手决定,提供向后兼容的最佳方法就是写一个转换器,把1.0版的档案转成2.0 版档案.她开始打程序,喀嗒喀嗒,硬盘转呀转,鸡飞狗跳.大约两周后弄出一个还 不错的转换器.不过史快手的客户不太高兴.史快手的程序等于强迫全公司一次 升级成新版本.史快手最大的客户Nanner Splits无限公司拒绝购买新软件.他 们要确定2.0版软件能不经转换使用1.0版档案.史快手决定写一个回溯转换器 并挂在〃存盘〃功能内.这就有点复杂了,在使用2.0版的功能时似乎一切正常, 不过等要把档案存成1.0格式时就有问题了.你会发现前半小时用的新功能都无 法以旧的文件格式储存.所以回溯转换器又写了两周,而且也不是很好用.这样 子4周就过去了 而好脾气软件公司的罗杰先生是那种一切照规矩的人,没拿到规格前是绝对不 写程序的.他花了20分钟设计出和史快手一样的向后兼容功能,并且写出大意 如下的规格: 如果开启的档案是由旧版产品所建立的,就把档案转成新格式. 把规格先拿给客户看看,客户说话了〃等一下!我们不想让全公司都升级!”所以 罗杰先生再想想后把规格改成: 如果开启的档案是由旧版产品所建立的,就把档案在内存内转成新格式.等要 储存这个档案时,使用者可以选择存回旧格式. 这样又用了 20分钟. 罗杰先生的老板是个面向对象狂.他看看这份规格,觉得有点问题并且建议用另一种架构。 把程序重组成使用两组接口 : V1和V2.V1包含所有版本一的功能,而V2则是继承V1 并加上所有新功能.这样V1::Save可以处理向后兼容事宜而V2::Save可以储存 所有新东西.如果你开启V1档案后使用到V2的功能,程序可以马上警告你,你必 须转换成新文件格式或放弃使用新功能. 又20分钟去了。 罗杰先生不太高兴.因为重组程序要花3周而不是他原先估的2周!不过的确优雅 地解决了客户所有的问题,所以他还是回去照做了. 罗杰先生所花的时间总共是3周加1小时.史快手则花了4周,不过史快手的程序 没那么好. 这个故事告诉我们,只要举的例子够怪,什么事都可以证明.对不起,刚才是开玩笑 的,我不是这个意思.这个故事真正要说的是,当你以人用的语言设计产品时,只 需要花几分钟就能考虑多种可能并且修订及改进自己的设计.没有人会觉得在 字处理器里删掉一段有啥大不了的.不过当你用程序语言设计产品时,反复设计 就得花上好几周了.更糟糕的是,某段程序可能只花程序员2周就写出来,可是他 会一直死抱着那段程序,不管程序错得多么离谱.虽然史快手的程序并非最佳的 架构,可是不管她老板或客户说什么,都无法说服她把那段漂亮的转换程序丢 掉.结果最终的产品很容易变成最初设计和错误设计以及理想设计间的妥协.它 是”我们所能做到的最佳设计,因为这些程序都写好了,而我们又舍不得把写好 的程序丢掉重写”.如果光是〃我们所能做到的最佳设计”,没有后面那些废话会 更好. 所以这就是写规格的天字第一号理由.天字第二号是节省沟通时间.当你有写规 格时,对于程序应有的作用只需要讲解一次.团队里其他人只要读规格就好了. 品保人员读了规格就知道程序的动作同时也知道如何测试.营销人员读了规格 就能写出嗳昧的资料,放在网站上宣传尚未出现的产品.事业开发人员没好好 读规格却在幻想,以为产品能治疗秃头肿瘤还有毒瘾,不过这样能吸引投资者, 所以没啥关系.开发人员读了规格就知道要怎样写程序.客户读规格则是要确定 开发人员正在制作他们想买的产品.技术作者读了规格才能写出好的手册(然后 被遗失或丢掉,不过这是另一个故事).经理也读规格,才能让自己好像知道经 营会议的内容.如此类推. 这所有的沟通在没有规格时还是会发生,因为这都是必要的,不过这时的沟通 都是特别安排的.品保人员无论如何都得玩这个程序,看到有任何不对劲就会再 度中断程序人员,并且问另一个程序应该怎么动的蠢问题.这不只会毁掉程序 人员的生产力,而且程序人员也习惯照自己程序的写法回答问题,而不会回答” 正确的答案”.结果品保人员实际上是用程序来检验程序,而非以设计来检验程 序,而后者应该会好一点吧. 当你没有规格时,可怜的技术作者会遇到很好笑的事(以极悲惨的方式).技术 作者通常没有中断程序人员的特权.在很多公司中,如果技术作者习惯中断程 序人员问些程序运作上的问题,程序人员会找经理告状,说这些该死的作者让 他们什么事都做不了,请他们闪远一点.经理为了想提升生产力,就禁止技术作 者不要再浪费程序人员宝贵的时间.这种公司很容易分辨,因为它们的说明档 和手册里讲的没比画面上多多少.当你在画面上看到以下的讯息 你要启动LRF-1914支持吗? …当你点选”说明”就会看到一段叫人哭笑不得的内容:允许你选择LRF-1914支持(默认值)或无LRF-1914支持。如果你需要LRF-1914支持,点选〃是〃或按”Y”.如果不需要LRF-1914支持,点选〃否〃或按”N”。 嗯,谢了.很显然技术作者试图掩饰他们不知道LRF-1914支持是啥的事实.他们 不能问程序人员,因为(a)他们太害羞了,或是(b)程序人员在海得拉巴(印度) 而他们在伦敦,或者(c)管理阶层禁止他们中断程序人员或是其他各种数不清的企业弊病,不过根本的问题在于没有规格. 写规格的天字第三号理由就是没有详细规格就无法订出时程.有些场合没有时程 是可以的,例如你打算花14年研宄的博士论文,或打算写下一版等好了就会推出 的毁灭公爵游戏.不过几乎所有真实的事业都必须知道事情需要多久完成,因 为开发产品是要花钱的.你不可能不知道价钱就买牛仔裤,那么一个负责的企 业怎么能不知道要多少还有要多少钱,就决定是否制作某个产品呢?想多了解 时程安排,请参考无痛软件时程. 有个很糟糕的常见错误,就是对某个项目的设计争论不休,结果永远无法排除 争议.Windows 2000的首度开发人员Brian Valentine就有句名言”10分钟内给 你决定,否则下一个免费”(译注:美国著名的披萨连锁店达美乐有一句广告标语 “30分钟内送达,否则下一个免费”.同样的,Brian会在10分钟内决定,否则会免费 给你下一个决定,不过要老板下决定本来就不用付钱给你的,不是吗?) 在很多的程序开发组织中,每次出现设计争议总是没有人愿意作出决策(通常都 是因为政治理由).所以程序人员只去做那些没有争议的项目.等时间消逝而所 有困难的决定都会压到最后才决定.这些项目很可能会失败.如果你针对某项新 技术开了家新公司,却注意到公司有结构性问题无法作出决策,你最好关门大 吉把钱退还给投资者.因为你永远都无法推出产品. 写规格是处理这些烦人设计决策的好方法,这些问题有大有小,不过没写规格就 看不到.即使很小的决策问题也可以写规格搞定.举例来说,如果你正在建一个 会员网站,你们可能都会同意,当用户忘记密码时应该发信告知密码.很好, 不过对写程序来说还不够.要把程序写出来得知道邮件中实际使用的文句.大部 份公司都不认为程序人员能撰写用户实际接触的文句(而且通常都有很好的理 由).所以会要求营销人员或公关或是其他文学素养好的人决定讯息的文句内容. 〃王大明先生,这是阁下忘记的密码.希望阁下往后能小心一点.〃当你强迫自己 写出一份良好而完整的规格时(我很快就会详述这一点),就会注意到这所有的项目并且把它解决,或者至少标示出来以便修正. 好了.我们现在应该都能同意.规格是一切的根本.我怀疑大部份的人是否懂这一 点,另外我讲的虽然有趣,却不知是否真能让你学到新东西.那么为什么人们不写 规格呢?绝不是省时间,因为根本不会省,而且我认为大多数程序员都知道(在 大部份组织中,唯一存在的”规格”都是断简残篇,是程序员写好程序后解说某 该死功能第三百遍后,用记事本打出来的一页文字文件. 我认为真正原因是多数人都不喜欢写东西.瞪着空白的屏幕会让人感觉极度地 沮丧.我个人克服写作恐惧的方法是去学校参加写作课,一星期写3到5页的短 文.写作就像肌肉一样,写得愈多就愈能写.如果你必须写规格又写不出来,开 个期刊定讯,建一个weblog,上个创作写作课程,或是写封信给亲戚或四年未 联络的大学室友.任何把文字填到纸上的活动都能增进你写规格的技巧.如果你 是个软件开发经理而该写规格的人写不出来,把他送到山里面上两周创作写作 课吧. 如果你未曾在一家有写功能规格的公司做过,可能会没看过功能规格.我会在 本系列的下一篇中展示一篇简短的规格范例供你参考,另外我们也会讨论一份 好的规格必须具备的元素.