操练严格才好打仗

作者:周思博(Joel Spolsky)
译:Paul May梅普华
2001年11月20日,星期二
属于Joel on Software,http://www.joelonsoftware.com

我觉得VMWare的实在是棒到不行。过去几星期我们要让CityDesk在各种32位元的视窗上都能动,这个程式帮助非常大。我安装了几十套虚拟机器,有单纯的DOS分割 (作为安装其他OS的起点)和各种NT 4.0的组合,还有中文和希伯来文的Win2K (虽然我们的程式是用英文也没什么特别的东西,还是在这些系统上找到各式各样的问题),还有从1995年8月起发行五花八门的运 95/98 / Me的版本,甚至还有包括一台主网域控制器的小型网路来测试[FogBugz的](http://www.fogcreek.com/FogBUGZ)的安装。

![VMs.gif(http://www.joelonsoftware.com/pictures/VMs.gif)

要让程式在五花八门的的Windows系统上都能动是件大工程,这是Java的等「写一次程式,到处都可跑」系统的真正诉求。理论上如果用的Java虚拟机器,辛苦的是要提供这所有平台相容性的虚拟机供应商。可是实际上的Java程式师都已学到,程式本身实在是太脆弱太敏感,达不到完美的效果。以前我用的Java开发某个游戏时就了解到,由于Java的无法保证行程执行的时间(这种妥协似乎没什么问题,反正CPU排程基本上就是无法预测的),实际上会让某些行程在麦克塔上永远卡住,要等其他行程尝试执行I / Ø才会继续。这和我预期的 _不一样_而且也让我的游戏在麦金塔上不太刺激。(这是1996年的事。所以不要写信告诉我要如何避开或修正,也不用解释这个问题已经修好了。)

昨天遇到的“当日之虫”就是个类似的整人例子.Michael用古老的Windows API 的GlobalAlloc配置了一些记忆体。然后呼叫另一个函数GlobalSize取得该记忆体的大小。在我们的开发系统上(视窗 2000年),GlobalSize会传回当初配置时相同的值配置。13个位元组,GlobalSize就会传回13。

某个用Windows 98的使用者回报了一个问题:“复制贴上没有作用”。就像上面的画面所显示,我装了一套Windows Me VM还有VB6。在用除错器逐行追踪程式时,我注意到GlobalSize呼叫,回想起赢 95时代GlobalSize会传回真实配置到的区块大小,数字会比你要配置的_大_而且通常是64的倍数。这就是问题所在。

现在,改变GlobalSize行为的微软程式师可能认为自己并没有破坏任何东西.GlobalSize函数的文件明白地写着:「。记忆体区块的大小可能会大于比记忆体配置时要求的大小」事实上微软人可能认为,让GlobalSize传回所要求的大小是个无害的小小改进。很显然的,旧程式码并不会相信GlobalSize的传回值,所以能不受影响继续动。有什么理由不改进这个函数呢?

并不是每个程式师在使用每个函数时都会细读对应的每一行文件,另外只要程式会动了,就会去做其他事情。更何况文件里并没有把所有东西都写得很清楚,像我这里讨论的这类细节就很少写在文件里而这正是这类问题发生的原因其实除了微软人以外,全世界都已发现这个问题,看看酒(译注:。一个视窗环境模拟器)程式师失败的原因,当他们推出 第二个 网路浏览器时,突然间每个人都注意到原先赖以让网页显示正常的某个问题不见了。另外IE6依照标准去处理表格中文字的行为,结果无数编HTML网页的人都在哀叹,因为他们的网页用IE6来看都变成和婚礼喜帖一样靠左对齐了。

我们要怎么处理这种狗屎呢?拉里 壁[说过一句很有名的话(http://www.oreilly.com/catalog/opensources/book/larry.html):「大家直觉上都知道,要电脑程式彼此沟通,最好的方法就是提供时要严格,接收时要宽松。」我认为HTML的演进已经证明这并不是什么好主意。事实上API对于输入参数愈严谨,程式愈有可能在奇怪的状况上仍旧运作的.java的设计者就做得很对,他们决定的Java的规格应该要清楚明确,不要让编译器开发者有任何选择余地(至少不要像ç那样无道理的宽松,连基本型别的大小都不定)。俄罗斯[苏沃洛夫元帅](http://www.ganesha.org/hall/suvorov.html)说得好:「操练严格才好打仗」你希望你的编译器和开发环境尽可能的严谨;你希望能让GlobalSize传回任意乱数,这样才不会养成习惯去依赖一些某一天会消失不见的机制;你希望在中文的Windows 2000上套用法国的区域设定,再搭配离谱的配色,德沃夏克键盘,轨迹球,640×480 VGA显示模式和大大丑丑的字型,然后拿来当开发环境,这样才会记得在程式里做所有对应的调整。这样一来你的应用程式就会柔轫坚强,连有人小数点是用逗号而非句点这种蠢问题也能大笑面对你的程式会用俄国口音说:哈哈哈,我都拿逗点来当 早餐

总而言之,这是让软体在几亿台电脑上都能跑的方法。只在一台电脑或是在一个受控制的环境下开发程式是很简单,不过你会变得软弱无力。总有一天你要在_第二台_ 电脑上执行,然后你就会熬夜在那台电脑上安装完整的开发环境,然后再查两个小时之后,终于发现自己没有考虑到安装路径里可能出现空白字元,因为第一台电脑没有这种情形。

可以指望的是,未来虚拟机器的概念(不管它是Java中,.NET还是别的玩意)将会减少这种痛苦,不过时候还未到。现在我还是很高兴能花十分钟除错,就能让喜欢把视窗文字设成粉红色或橙色的人都能正常执行我的程式。在一整年的开发时间里,我们大概用了三星期去修正组态相关的问题。小小的代价却让潜在客户群由美国版的Windows 2000扩展到整个NT 4,95,98,Me,和XP家族,再加上全球各种语言版本。酷。

这些网页的内容为表达个人意见。
所有内容版权所有©1999-2005,作者Joel Spolsky。版权所有。