权衡的艺术
Hoping翻译
来自:www.pragmaticprogrammer.com
你是怎样开发软件的?
在那些以编写软件为生的人们之间有一个常见的争执。有些人坚持认为在编写代码前必须先要有一个完整的模型,那些过早进行编码的人只不过是一些“在地狱中编码”的hacker。
然后,就会有另外一群人说,嗨!等一下。你无法从一个简单的预先模型中学到足够的知识。你必须得编写某些形式的代码。否则,你很可能会遗漏掉一些重要细节,甚至创建出一个无法构建的模型。
正确答案
那么哪一方正确呢?是整天侵淫在代码之中的那一方呢?还是坚持在思考代码前必须先完整地建立对世界感知的模型那一方呢?
嗯,他们在某种程度上都是正确的。至少,他们在试图解决同样的问题--获取正确实现一个系统的足够知识。
请注意,软件项目和其他工程学科中的项目不同。软件项目在本质上是以发现为中心的项目。随着时间的过去,你和你的团队会学到更多的知识。你对客户、应用、环境以及发起者的认识也会随着项目的进展而增加。
你必须得做好适应新发现的知识的准备。典型的瀑布方法的错误就在于根本没有任何反馈。在瀑布模型中,低层编码中的任何发现根本无法影响到需求和架构。然而,这些低层细节对于理解更高层的东西来说常常具有深远的影响。
降低风险
降低风险是传统工程的核心。当建造一座桥梁时,你不会考虑把它建造成一座永远不会倒塌的完美桥梁。相反,你只会考虑它能经受500年的风吹、200年的水淹、最大3倍于所期望的承重,等等。如果不做这些设计权衡,那么所有的桥梁都将是从桥面到地面的实心混凝土,都将有500英尺宽。工程的全部就是做这些折中,软件工程也是如此。
软件工程的困难在于:大部分的风险都存在于构建它的过程以及所完成的结构之中。原因就是其发现的本质。
知道了要在前进中不断地进行发现,那么问题的核心就在于要使所发现的东西使你已完成工作失效的风险最小化。
那些直接去拼凑产品代码的人在开始之前就已经陷入麻烦之中:(由增加的知识所导致的)方向上大的变化此时更改起来最为困难,也最为昂贵。
那些建议在做任何实现之前要先建立完整模型的人,同样也冒着在创建产品代码期间会出现重要发现的风险。作为现实抽象版本的模型,必然会失去一些细节。而恶魔很可能就潜伏在这些细节之中。
于是,就有一些人试图在这两个极端之间进行平衡,他们建立一点模型,就进行一些编码,他们使用一次性的原型或者代码曳光弹进行建模。Usenet中许多关于这个主题的讨论都集中在是宽度优先还是深度优先;何时建模以及何时编码等细节之上。针对这个问题,不同的方法会给出不同的建议。
方法就是我们自己
极限编程是基于降低风险的前提之上,当今所有其他流行设计方法在某种程度上亦是如此――不管它们是否承认这一点。
已公开的方法都在试图回答下面问题:“为了创建一个软件系统,我和我的团队如何才能以最为经济的方法获取最多的问题领域和解决方案领域知识。”
很明显,风险固有地存在于项目的发现过程之中。然而,该发现是一直在进行的,我们无法承受游戏后期的重大发现。在理想情况下,我们希望能够预先发现我们希望知道的一切,并且完全理解它们。现实肯定不会是这样的,所以每个方法都试图创建出一个环境,在其中你能够尽可能早地做出最重要的发现。一个特定方法最有价值之处就在于它是如何降低在晚期出现的关键发现的风险的。
不过,这些答案对每个人来说都是不同的。答案和你的团队、项目、经验、问题领域、工作环境等相关。如果你曾经发现一个方法很适合于一个项目,谁也无法保证它会适合于下一个项目。如果所列出的这些因素中的任何一个发生变化,很可能就要对过程进行修订。
它并不完美
你已经看到,和算法或者坚固的机器指令序列的质朴之美不同,它并不完美。过程和方法依赖于人去维持它们,去理解将被检查的要素。而人是很容易犯错误的。
所以在最后,我们再回到对管理权衡的想法。你可以在一个项目的对象模型上浪费6个月的时间,结果在实现期间却发现你错误的理解了客户的性能需求。你可以很早就开始实现,把自己锁定在一个无法支持一些你还不知道的重要需求的设计和架构上。
或者,你可以对权衡进行评估以最小化总的风险,接着分析一点、设计一点、编码一点。每个任务所占的相对比例、顺序、反馈的数量――所有这些对每个项目、每个实践者都是不同的。不存在在任何时间、任何场合都正确的答案。所以,一定要注重实效,作出最适合当前问题、当前团队、当前环境的选择。
所以,当你下次进行计算机是工程实践还是艺术的讨论时,请考虑一下权衡的艺术。其他的工程学科必须要建立在和物理世界有关的权衡之上;我们必须要面对和我们自己相关的权衡。
然后我们就可以开始开发软件了。
本文地址:http://com.8s8s.com/it/it36961.htm