听说过SEMA吗? 这是一套相当深奥的系统, 可以测量软件团队的好坏. 等一下! 不要急着连过去看. 光是要搞懂那东西大概就要花上六年了. 所以我自己有一套无责任的简易方法来衡量软件团队的质量. 这套方法的好处是只要花3分钟左右. 省下的时间足够让你念趟医学院.
The Joel Test
你有使用原始码控制系统吗?
你能用一个步骤建出所有结果吗?
你有没有每天都重新编译建立(daily builds)吗?
你有没有问题追踪数据库(bug database)?
你会先把问题都修好之后才写新的程序吗?
你有一份最新的时程表吗?
你有规格吗?
程序人员有没有安静的工作环境?
你有没有用市面上最好的工具?
你有没有测试人员?
有没有在面试时要求面试对象写程序?
有没有做走廊使用性(hallway usability)测试?
约耳测试 (Joel Test) 的好处是每个问题都很容易回答是或否. 你不必计算每天写的程序行数或是每个转折点的平均问题数量. 只要答"是"就加1分. 约耳测试的缺点是绝对不能用来确保核电厂的安全性.
得12分是完美, 11分勉强可接受, 不过10分以下(?0分)就表示问题大了. 事实上大部份软件组织都只拿到2或3分, 这些组织都岌岌可危, 因为微软随时都是以12分的水平运作.
当然啦, 这些并不是决定成败的唯一因素: 特别是当你的优秀团队做些没人要的产品时(对, 没人要). 另外也可能有那种"高手"团队, 即使完全不鸟这些东西却还是能做出改变世界的梦幻软件. 不过除此之外其它人都一样, 如果你能把这12件事做好, 就能建立一个能稳定出货的纪律团队.
1. 你有使用原始码控制系统吗?
我用过一些商用原始码制系统也用过免费的CVS, 我可以告诉你CVS相当不错. 不过如果你没有原始码控制系统, 当需要程序人员合作时你就会被压垮了. 程序人员没法子知道其它人做了些什么. 也不能轻易回复成出错前的状态. 原始码控制系统还有另一个优点, 就是原始码会被注销(check out)到各个程序人员的硬盘里 -- 我还没看过哪个用了原始码控制的项目会遗失大量程序.
2. 你能用一个步骤建出所有结果吗?
我的意思是: 从最新的原始码快照开始, 要花多少步骤才能建立出货用的软件? 好的团队会有单个脚本档案, 只要执行这个档案, 就会从头注销所有档案, 编译每一行程序, 建立执行文件(包含所有不同版本,语言以及 #ifdef组合), 制作安装程序, 并且产生出最后要用的媒体形式 -- 光盘片编排, 网站下载或是其它各种形式.
如果这个程序不只一个步骤, 就会容易出错. 另外当出货时程紧逼时, 修正"最后的"问题,制作最终执行档等等的过程要能飞快地完成. 如果程序编译和安装文件制作等动作要20个步骤才能完成, 你一定会急疯掉并且做出一些蠢事.
就是为了这一点, 我前一家公司把原本用的WISE换成InstallShield: 我们需要能透过NT工作排程器, 在晚上用描述档自动执行的安装制作程序, 由于WISE不能透过工作排程器半夜执行, 所以我们就把它丢掉了. (亲切的WISE员工跟我保证他们的最新版一定会支持夜间执行.)
3. 你有没有每天都重新编译建立(daily builds)吗?
在使用原始码控制工具时, 有时候程序人员会不慎登入(check in)某些内容而导致编译失败. 举例来说, 某人新增加了一个原始程序文件, 整个程序在他的机器上都能正常编译, 可是却忘记把新增的程序文件加到原始码控制程序库中. 结果这位仁兄健忘并快乐地锁上机器回家了. 其它人都不能做事, 所以也只好很不爽地回家.
导致编译失败非常糟糕(又经常发生), 这时每天重新编译建立就很有帮助了. 它能保证不会有漏网之鱼. 在大型的团队中, 要确保能立即修正编译失败的最佳方法就是每天下午(像是午餐时间)重新编译. 大家在午餐前尽可能的登入档案. 等大家回来的时候已经编译完毕. 如果结果正常, 很好! 大家可以注销最新版的原始码继续工作. 如果有问题就去把它搞定, 而其它人还可以用前一版没问题的程序继续干活.
我们Excel团队有个规定, 导致编译失败的人必须从此负责重新编译的动作(作为处罚), 一直到有其它人出错为止. 这是个让人不要导致编译失败的好诱因, 同时是个让大家轮流处理重新编译的好方法, 这样大家都会知道怎么做.
我这篇文章里有更多每日重新编译的数据aily Builds are Your Friend.
4. 你有没有问题追踪数据库(bug database)?
不管你说什么. 只要你在写程序(只有一个人写也一样), 如果没有一套良好的数据库列出程序中所有的问题, 一定会产生质量低劣的程序代码. 很多程序人员自认能把问题清单记在脑里. 才怪. 我从来没法子一次记住超过二或三个问题, 而且会在第二天早上或是赶着出货时把它们全部忘掉. 你一定要正式的记录问题.
问题数据库可大可小. 一个最简化的有效问题数据库必须包含每个问题的下列数据:
重现问题的完整步骤
应该看到的行为
实际看到的(有问题的)行为
被指派的负责人
是否已修正
如果你是觉得问题追踪软件太复杂才不追踪问题, 建个5栏的表, 填上这些重要字段然后开始用吧.
想深入了解问题追踪, 请参阅无痛错误追踪.
5. 你会先把问题都修好之后才写新的程序吗?
古早第一版的Microsoft Word for Windows 被视作为"死亡行军"型项目. 进度一直落后. 整个团队的工作时间长得离谱, 项目却一延再延三延, 大家都承受到无比的压力. 拖了几年后那个鬼东西终于上市了, 微软就把整个团队送到Cancun (墨西哥著名海滩) 渡假, 然后再坐下来做些深度反省.
他们发现项目经理过度坚持要保持"进度", 结果程序人员只能赶工写出烂程序, 而且正式的时程并没有包含错误修正的阶段. 没有人试图要减少问题数量. 而且实际上刚好相反. 有个程序人员要写程序计算一行文字的高度, 结果他只写了"return 12;" 并等问题报告出炉说这个函数功能不对. 时程表变成一份等着被转换成问题的功能列表. 事后检讨时称之为"无穷错误法".
为了修正这个问题, 微软全面采用所谓的"零错误作法". 很多公司里的程序人员都不禁窃笑, 因为听起来像是管理阶层认为能用行政命令降低错误数量. 实际上"零错误"是指无论何时都要先修正错误才能写新程序. 原因如下.
一般来说, 愈晚修正错误, 修正所付出的成本(时间及金钱)愈高.
举例来说, 当你打错字或出现编译器会发现的语法错误, 要修正只是小事一件.
当你的程序第一次执行出错时, 应该也能立即改正, 因为整个程序还在你脑海里.
如果要为几天前写的程序除错, 应该需要回想好一阵子, 不过当里重读所写的程序之后, 就会记起所有细节并在适当时间内把问题修好.
不过如果你要为几个月前写的程序除错, 很可能已经忘掉了一大半, 要修正就是难上加难. 你也可能正在替别人的程序除错, 而当事人可能正在阿卢巴渡假, 这时候除错就像科学一样: 你得条理分明小心翼翼地慢慢来, 而且也无法确定要多久时间才能解决.
另外如果要为已出货的程序除错, 要修正问题的代价可是难以估算的.
要立即修正问题的理由之一, 就是因为这样做能少花点时间. 另一个理由是写新程序的时间比修正现有错误的时间较易估计. 举例来说, 如果要你估计写个串行排序的程序需要多久, 你应该能估算得相当准确. 不过如果说你的程序在装了Internet Explorer 5.5之后有问题, 要估计需要多久才能修好这个问题, 恐怕你连猜都不会, 因为你不知道(当然不知道)问题哪儿来的. 要找出问题可能要花3天, 也可能只花2分钟
我的意思是如果你的计划时程里有很多错误待修正, 这种时程是不太可靠的. 不过如果把已知的错误都修好了, 所剩的就只要新程序了, 那么你的时程就会变得非常准确.
把错误数量维持在零还有另外一个优点, 就是面对竞争时反应更快. 有些程序人员认为这样做能让产品随时能推出. 所以如果竞争者推出某个杀手级新功能来抢客户, 你只要把那个功能加上去就可以立即出货, 不必去修正累积下来的大量问题.
6. 你有一份最新的时程表吗?
我们在这里要谈谈时程表. 如果你的程序对公司非常重要, 有太多理由可以说明预知程序完成时点有多么重要. 程序人员不爱订定时程可是恶名昭彰. 他们会对业务大叫: "该完成的时候就会完成!"
但是问题不可能就这样算了. 业务人员有太多的计划决策必须远在程序出货之前做决定: 展示, 商展, 广告等等. 而做决定的唯一方法就是定出时程并随时更新.
拥有时程的另一个重点是逼你决定要制作哪些功能, 并且能逼你剔除最不重要的功能而避免功能过度膨胀(featuritis, 又名scope creep).
要维护时程表并不困难. 请参阅我的文章Painless Software Schedules, 文中叙述建立好用时程表的简单方法.
7. 你有规格吗?
写规格像用牙线: 大家都同意这是好事, 却没有人真的在做.
我不知道为什么, 或许是因为大多数程序人员都讨厌写文件吧. 所以当全是程序人员的团体 面对问题时, 自然倾向用程序代码而非文件来表示答案. 他们宁愿跳进去写程序也不愿先写规格.
在设计阶段发现问题时, 只要改几行就能轻易修正. 等程序写出来之后, 修正的代价就高得多了, 代价包含了情感 (人们讨厌块弃程序代码) 和时间, 所以会抗拒修正问题. 通常未依据规格制作的软件 最后的设计都很糟, 而且进度完全无法控制. 这似乎就是发生在Netscape上的问题. 它的前四版变得一团乱, 结果管理阶层愚蠢地决定 把程序丢掉重新开始. 然后他们在Mozilla