没有事情像表面看起来那么简单

作者:周思博(Joel Spolsky)
译:Paul May 梅普华
Monday, March 04, 2002
属于Joel on Software, http://www.joelonsoftware.com

CityDesk有个小小的使用性问题。

问题是这样的:你可以用选单由网路上汇入档案(Import Web Page),也可以用滑鼠拖拉磁碟里的档案汇入CityDesk。不过没有选单可以汇入磁碟中的档案,所以大家不是没有发现可以这样做,就是[尝试] (http://discuss.fogcreek.com/citydesk/default.asp?cmd=show&ixPost=331)用Import Web Page功能汇入磁碟中的档案,而后者当然也是不能用的。

我认为用两页的精灵可以轻易的解决这个问题。大概的方法是用精灵的第一页问「你要由哪里汇入资料?」,如果你选「磁碟」,第二页就提示你输入档名;如果选择「web」,第二页就提示输入URL路径。

我几乎要开始实作,不过还是停下来着手写一份迷你规格。下面是这份规格的全文:

**第一页
** 你要由哪里汇入资料?(磁碟/Web)

第二页(磁碟)
标准的开启档案对话盒**第二页(Web)
** 有迷你网页浏览器的URL输入画面

突然间我想到一件事。有办法把通常由OS提供的开档对话盒_放在_ 精灵里吗?

呃…

我去查过了。结果是可以的,不过不太好玩而且要花几个小时工夫。那么可以不用精灵来做吗?我把规格重写成:

两个选单:
1)由Internet汇入网页 - > 显示URL对话盒
2)由磁碟汇入网页 - > 显示开档对话盒

好多了。三分钟的设计省了我几小时的程式工夫。

如果你这辈子写过20分钟以上的程式,可能已经发现这个很好的基本原则: 没有事情像表面看起来那么简单.

就连复制一个档案这么简单的动作都充满陷阱。如果第一个参数是目录会如何?如果第二个参数是档案又如何?如果目的地已经有相同档名的档案又会怎样?万一没有写入权限又怎么办?

如果档案拷到一半出错要如何?如果目的地是需要认证才能继续的远端机器又如何?如果档案很大而连线很慢,必须显示进度栏时又会如何?万一传输速度慢到_几乎_ 完全不动…你要等多久才放弃并传回错误讯息呢?

有个好方法可以用来面试应征测试工作的人,就是要他针对一件简单的操作,把所有可能出错的地方全都列举出来。微软对面试测试人员有个经典题目:如何测试开档对话盒?优秀的测试人员可以滔滔不绝地列出几十种测试项目(在你选好档案,要按「 开启 」之前,另一个使用者把原本存在的档案杀掉了)。

好了,所以我们得到一个定理:没有事情像表面看起来那么简单。

软体工程里有另外一个定理,就是随时随地都要尝试降低风险。其中一项必须避免的重大风险是进度风险,就是某件事花的时间比预期多。进度风险的坏处在于你会被老板吼而很痛苦。如果你觉得这没什么,可以改由经济观点考虑进度风险的坏处。如果因为当初评估需要一周而决定要做某个功能,事后才发现其实需要20周,那么前面的决策就错了。如果你早知道需要20周很可能就会做不一样的决定。而错误的决策愈多,印有你公司标志的购物袋愈有可能流落到资产清算的仓库,而同时间你的前执行长还在怨叹「真惨啊,我们还没有被烂公司报导前就倒了!」

「没有事情像表面看起来那么简单」再加上「降低风险」只会导出一个结论:

你必须先做设计再去实作。

我很抱歉让你失望了。没错,我知道你看过Kent Beck的书,而且现在认为不先设计而直接实作是正常的。很抱歉,这并_不_ 正常。改程式就是**没法子** 和改设计文件「一样简单 」。大家一直都这样说,不过这并不对。「现在我们都用Java和XML这种高阶工具,几分钟就可以改好程式,为什么不直接在写程式时做设计呢?」我的朋友,你可以替你老妈装上轮子,不过她并不会因而变成巴士。另外如果你自认能把错用执行绪的档案复制函数,重整改正成先占多工的作法,而且速度和我写这个句子一样快,你根本就在自己骗自己(deep denial)。

无论如何,我不认为极限程式设计真的在提倡零设计。他们只是说「不要做无谓的设计」,而这一点是没有问题的。不过大家_听到_ 的不是这么回事。大部份程式师都尽可能地找寻能不在实作前先做基本设计的借口,所以他们就像捕蚊灯里的蚊子一样黏住「无设计」这个想法。这其实只是偷鸡不着蚀把米的另类懒惰。我懒得先在纸上设计功能所以直接写程式,程式做得不对只好再花时间修正,结果只会花更多的时间。还有更常见的状况,就是程式写错了可是来不及改正,于是产品的品质低落,只好一直找借口解释东西为什么「必须写成这样」。根本就是懒散又不专业。

当Linus Torvalds痛斥设计时谈的是巨大的系统,这种系统必须逐渐演进,否则就会像Multics那样死路一条。他说的并不是你的档案复制程式。人们认为Linus有很清楚的计划,确实知道往后要怎么进行,无怪Linus会不怎么看重设计。所以别上当了,这种作法很可能并不适合你。何况Linus比我们要聪明 多了 ,他能做的事我们一般人是做不来的。

渐进式的设计和实作是好的。常常发行也是好的。不过就套装软体或大众市场而言,频繁的发行新版会让客户疯掉,并不是个好主意,应该改成在内部密集的发行。太拘泥于设计细节会浪费时间,我从来没看过哪个专案,会因不需动脑的流程图或UML或CRC或是其他流行玩意而获益。Linus说的那些有一千万行程式的超大型怪物系统 应该 要逐渐演进,因为人类确实不知道要如何设计那种规模的软体。

不过当你坐下来要写档案复制的程式,或是计划下一版软体的功能时,一定要做设计。不要让那些说法迷惑了你。

你可以在四月29到五月一日间,到麻州剑桥的 Cutter Summit和我当面讨论,我会和Tom DeMarco, Kent Beck和其他人一起。

这些网页的内容为表达个人意见。
All contents Copyright © 1999-2006 by Joel Spolsky. All Rights Reserved.