您的位置:首页 > 其它

软件随想录(local.joelonsoftware.com/wiki)-2001年11月20日 操练严格才好打仗 - A Hard Drill Makes an Easy Battle

2013-02-19 15:00 281 查看
2001年11月20日
操练严格才好打仗 -
A Hard Drill Makes an Easy Battle

 

The Joel on Software Translation Project:操练严格才好打仗

From The Joel on Software Translation Project

Jump to:
navigation,
search

操练严格才好打仗

作者:周思博 (Joel Spolsky)

译:Paul May 梅普华

Tuesday, November 20, 2001

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



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

昨天遇到的「当日之虫」就是个类似的整人例子。Michael用古老的Windows API GlobalAlloc配置了一些内存。然后呼叫另一个函数GlobalSize取得该内存的大小。在我们的开发系统上(Windows 2000),GlobalSize会传回当初配置时相同的值。配置13个字节,GlobalSize就会传回13。

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

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

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

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

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

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

这些网页的内容为表达个人意见。

All contents Copyright © 1999-2005 by Joel Spolsky. All Rights Reserved.

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐