《什么是软件设计?》又后记
----Jack Reeves, 2005,清气上升(译)
过去,人们经常问我:是否对我的文章《什么是软件设计》一文继续写点东西。我的回答基本上是:"不,真的不了。" 现在,我想让他们明白:不是因为我忘了那篇文章,或者其他什么改变了我的想法。让我对此做一点说明吧。
当文章发表的时候,我希望——实际上是期待,从所谓的业内专家那里听到一些的不同的声音。这是因为我写这篇文章的初衷之一就是想激发软件业内关于整个软件开发过程的讨论。但是,什么也没发生。
没有信件发到我所知的编辑手中,也从没有任何信件直接发给我。《C++ Journal》在发行那一期之后很快停刊了,我发现我的文章也像石沉大海一样没有反映。后来我继续做其它事情去了。直到1997年,亦或1998年,我才收到一封来自Bob Martin(他刚刚接手成为《C++ Report》的编辑)的email,信中写到:在Ward Cunningham的c2.com网站上,有一个关于我文章的wiki页面。这是我第一次——字面意义上的第一次,知道有人阅读了我的这篇文章(区别于我把文章拷贝给他看的人)。
我开始参与wiki页面讨论,偶尔参与到一些新闻组中,但出于一些我自己的原因,我没有故意地同他们站到一起:a)我有时候成为其它问题的焦点中心,b)很明显的,那些已经接受了我观点的人好像更有资格争论这方面问题,而我已经落伍了(我明确的记着Michael Feathers 是这样写的),c)而且落伍的不止一点点,这使我看上去似乎有一些与其相反的观念。不幸的是,大多数疑问听起来很像我曾经解决的问题,而使我自己解决那些问题花了我15年多的时间(记住,我在写那篇文章之前有这想法已经有10多年了)。
有些人总是不能放弃自己先前的观点,甚至不能理性地考虑一些问题,我已经厌倦了跟他们打交道了。这就好像向某些人解释法国人说的是不同的语言,而那些人坚信所谓"不同的语言"确切的意思是"英语不同的方言"一样。不论你怎么说,他们都将认为你的论点违反了他们的信仰,或者干脆置之不理,或者用他们相反的观点来赞许你。我看到过许多项目,贯彻了"源代码就是设计" (译者:作者应该是说那些没有文档的项目)的思想,但即使这些项目的工程师也经常拒绝接受"源代码就是设计"的实事。其实我那能"改善事物的犬儒(是指好斗的文人)主意精神等级"早就很高了。
现在,虽然情况还没发生什么变化,但我认为是我努力捍卫自己的时候了(而不是让其他人做这些事情了)。因此,我要针对那些常见的批判(我曾经看到针对《什么是源代码》的批判)做一些事情了。
1、最开始,我所看到的大多数批判可以总结为"如果源代码是设计的话,那么编码者就是设计师了;但很明显,他们不是,因此源代码不是设计"。这段话看上去很直白,但当你仔细分析他们说的内容,就会发现翻过来也是对的。这是个无理头式的论证,他们假设了写程序(或写代码)是制造业的打字活动。在逻辑上,这是以假设作为论据的悖论(Begging the Question)。但实事上,那些人说"你的假设(源代码就是设计)与我的假设(编码者是装配工人)相抵触,所以你的假设一定是错误的。"
某些人会建议我采取相同的手段,也就是使用"源代码就是设计"的假设。我接受了这个提议,并将它提炼成观点。我承认我的文章读起来像是为了证明"源代码就是设计",但那不是我真正想去做的。下面引自那篇文章的开始部分:"这篇文章假设最终源代码是软件的真实设计,并且接着验证一些根据这个假设的推论。我可能不能去证明这个观点是正确的,但我希望去展示,它确实解释了软件业中的一些被观察到的实事,..."
我并未宣称我要去证明"源代码就是设计";我将更乐意接受"设计"这个词是个广义概念。那篇文章的目的是:试图展示"源代码就是设计"的假设,是如何更好的解释业界诸多事实的。在这个假设的基础上,我仍然在等待人们给出更好的解释。
2、目前,人们正开始接受(勉强的)编码人员不是装配线上的工人了(部分可能是极限编程和敏捷开发方法的升温)。不幸的是,那并不意味着他们将乐意接受"源代码就是设计"的观点。以下的例子概括了那些wiki页面上的讨论。
"至于抛开完整的设计过程,而只保留源代码...哈哈哈哈哈哈哈哈哈哈,不是真的吧,哈哈哈哈哈哈哈哈哈哈哈哈^_^"
这真的使我很生气。我不明白,相当聪明的人却总是混淆"设计是过程还是产物的概念"。你应该想得到,一个大学毕业的人应该明白写论文的过程(只是个例子)和论文本身的区别吧!当然,你应该料想到任何有大学背景的人都明白,要达到同一个结果,可以有很多种不同的手段。
不过,人们一直坚持:我的"源代码就是设计"的意思是"不做设计,只要代码"。我不想再重复同样的话了,以下是我曾说过的内容:
"在软件工程里,我们在任何阶段都非常需要好的设计。特别是,我们需要良好的顶层设计。早期的设计越好,以后的设计将越容易。设计人员应该使用任何有帮助的东西。 结构图、Booch图、状态图、PDL等等。如果有帮助,那么就使用它。"
现在,我会用不同的词语了,我应该说我们需要好的构架(定级设计),好的抽象(类设计),和好的实现(底层设计)。我也应该谈一些有关UML图和CRC卡孰优孰劣的问题。但是,我是不会退步的:
"我们必须谨记,无论怎样,那些工具和符号都不是软件设计。最终,我们必须使用某种编程语言来创建真正的设计。因此,当我们得出设计的时候,我们不应该恐惧对它们的编码工作"。这是我的原则。我不去争辩我们应不应该"做设计"。无论你想怎样靠近"做设计"这个过程,我都会简单的坚持这个原则:直到你写完和测试完代码才算你完成"做设计"。
就个人来说,我认为一个把脚架在桌子上凝视着天花板"做设计"的人,跟一个用Rose玩UML的人一样认真。我总是这样想:你如果在付诸实施之前,尽力的使一些真实的想法进入思考范围,那么你将得到非常好的效果。然而,人们在用什么帮助他们思考的问题上,意见广泛的不一致。一些人用铅笔和纸,另一些人喜欢白板,亦或计算机工具;一些人喜欢和其他人讨论来产生灵感,另一些人则喜欢平和安静;一些人使用UML图感觉会好些,而另一些人宁愿用CRC卡。
直到有人坚持认为这些中间设计有权利转化成产品的时候,才使他们选择哪种工具做辅助变得重要起来。源代码才是关键。如果你获得了好的源代码,那源代码怎么转换来的还重要吗?如果你没得到好的源代码,那在写这些差代码前,你让人们产生其它垃圾还重要吗?
第一种情况,软件业中的每个人,无论待了多久,都看到过这样一些例子:某人坐在那,并且把出现在大脑中的第一个想法编写成代码。后来,当这段代码的缺陷很明显的时候,已经有太多的血汗融入到代码里了,以至于不能丢弃它,也不能把它写的更好了。是啊,我们都知道,一点点思考可以让我们走的很远。
另一种情况,一些专注于传统开发项目的人们,他们使用一种近乎苛刻的方法——在"设计"完成、讨论、审批等之前不写任何一行代码。他们认为你应该浪费很多该死的时间去产生一砣文档,而这些文档将在开始编码之后,随着日期逐渐失效。这是何苦呢?
你可能会认为:我们总能找到这两种情况折中的设计方法,只是不很多而已。我说没有这回事。我们验证软件设计的唯一方法只能是编译并测试它。没有银蛋,也没有所谓"正确的方法"去做设计。真正开始写代码的时候,花一个小时、还是一天、还是一个礼拜思考一个问题,可能产生很大的分歧。然而,花5分钟的测试,就可以暴露出你的错误。这些错误,无论你花多长的时间去思考,也可能想不到。我们只有在开发环境下的设计才是最好,接着对它进行重构。
最后的注释:我也没说源代码是唯一必要的文档。我在文章中特别的指出了:
"...对于软件工程来说,辅助文档就像它在硬件工程中一样重要。"
源代码可以是主要的设计文档,但它不是唯一必要的。
3、 我忍不住要做一些枝节问题的论述,这些问题跟上面的讨论有一定联系,也被带入到讨论中。它们是关于极限程序设计(XP)和敏捷设计方法方面的。这通常用短语表达成一个问题:初级程序员做什么?这个问题似乎是说:只有最最好的程序员可以同时"设计"和"编码"。为了弥补这种不足,我们必须有中间设计的所有步骤,并且,上面提及的产品(源代码)将由缺乏经验和天赋的初级程序员制造出来。
对于我,这好像是问"初级医生做什么?"一样。我知道医学上的习惯跟软件开发不好比对,但请宽容我片刻。医学上极多的习惯是非常恰当而刻板的(我们会开这样的玩笑"给两片阿司匹林先,明天早晨喊我")。不过,某个人在医学专业中,被允许称作医学博士之前,仍然被给予一些智力、教育和经验方面适当高的称谓。换句话说,我们想让我们的医生们知道他们正在做什么。
在软件开发中,关于初级程序员的问题真正归结为:试图让他们弥补智力、能力和经验方面的不足。显然的,很多人认为:我们只有强迫他们创建足够的UML图(或者其它什么图),达到足够多的审核,以及完成其他方面的琐碎工作,最终才能塑造出我们想要的东西,并进行正确的编码。这种没有根据的方法,在过去的时间里一直很盛行,我认为我没有理由会相信这种方法在将来仍然盛行。事实上,我的经验告诉我们:能恰当的使用类似UML工具,意味着他们拥有相当高的专业技巧和经验了。
4、我曾看到的另一个争论的焦点是:工程学上努力的目标是某种文档。某些人争论:工程学的目标是一种"产品",并且真正的工程师通常"建造"东西,而且那些"东西"是像任何文档一样多的工程学产物。
这种观点企图让人们混淆"其他工程师建造的东西"和"软件开发者创建的东西"两种事物,避而不谈"什么是软件设计?"的问题。坦白的说,那都是些废话。我将勉强承认:用一点点或者非正规设计文档制造"东西"的是工程师,虽然我猜测:那些案例中可能有部分文档(即使那是开发完后补的)。在任何案例中,我认为我可以准确的说:这样的工程产物只是一次性产品,并且通常由个人生产。
当"工程"开始朝多人配合的方向发展之时,或者当它达到常规制造业阶段之时,接着文档开始变得越来越大,就像现行工程产品一样。你最好相信丰田或摩托罗拉的工程师是产生文档的,我们将不考虑Boeing或Lockheed的工程师。当然,许多工程师同时做一些设计文档以外的工作,但是称自己为工程师的人们知道:在他们的领域中什么是设计文档,而且时常创建这些文档。我可以把这些说法用在 "软件设计师"吗?
捎带的,这个关于工程师和文档的争论不是源于我的想法,于是我从1979年的Datemation备份中摘取了一段代替了它,我十分同意它的观点。
5、我看到的最后一个观点,源代码级别太高了以至于不能称它为设计。至少一个评论家想称呼源代码为"说明书"。他(或她)的感觉是:真正的设计是不用编译器自然而然想出来的。在某种意义上,这只是定义的一个方面,但我仍然不同意。
一般能接受的定义是 :这个"说明书"陈述了"是什么",紧接着通过设计文档详细描述"怎么做"。虽然允许编译器怎样产生目标调买有一定的弹性,但那当然已不是跟创造有关的了。总而言之,如果文档足够的详细,足够的完善,足够的明确,并可以被机械的翻译了(不管是计算机还是装配线工人),那么你就有了一份设计文档;如果它仍然需要有创造性的人们去翻译,那就认为你没有得到设计文档。
在软件开发中,设计文档就是源代码清单。
浙公网安备 33010602011771号