Keeping Software Soft 让软件软下去

来源:互联网 发布:new balance淘宝店 编辑:程序博客网 时间:2024/06/11 04:21
Martin Fowler 的一篇文章:Keeping Software Soft
让软件软下去(呵呵,翻译的名字有些怪怪的)

原文在:
http://martinfowler.com/distributedComputing/soft.pdf

下面是中文译文:

让软件软下去

Keeping Software Soft
Martin Fowler

翻译:刘焱
2002年7月4日星期四

还记得你第一次写程序吗?我可记得:我敲入一些语句(用一些有点笨的语言写的),做一点
debug,我的机器就会给我回应。那时侯,可以很容易地让计算机做点事情,而且改改程序,让
计算机做别的事情也很容易,那不过就是稍微改一改程序,做一点 debugging 而已。别忘了,
总起来说软件就是要软。

当然,软件的绝对可变性是一种幻想。许多时候,一个软件开发者和一个正常人的区别,就在
于:软件开发者知道改变软件有多难。其实,真正难的不是改变软件有多难,而是在改变的同
时又不让它崩溃。

这个问题做软件的人也很早就意识到了,这也就是为什么临时设计(ad hoc design)——当程序
写到这里了才去设计——不适合于大型系统的原因。

为了解决这个问题,软件开发者们从其它工程学科中获得灵感。在这些学科中,把设计过程和建
造过程明确的区分开来。设计者和建造者的沟通是通过设计图,要建造什么东西、怎样去建造都
在这些图里面。

大部分的软件开发方法学,是以这种思想为基础的。不再是临时设计了,我们有了一种新的方法,
我把它叫做预先设计(up-front design)。就是说,在写程序以前先设计,一旦设计完成了,开始
写程序时,就不应该再有重大设计上的改变。当然,改变是在所难免的,但是预先设计流程明确的
目的,就是要尽量减少这种改变。

困难的是:要让这些设计尽可能的完备,以避免以后发生重大的改变,而重大改变往往会把设计弄
糟。这里就存在一个实际的问题——让设计从一开始就正确是很难的

需求变更的现实 有一个最根本的问题。有时,我不得不去调查,一些搞得一团糟的项目,看看有什
么办法可以让他们脱离苦海。每当,在这种情况下,我去和这些项目的开发者们谈话,我得到的,
似乎总是一些恸哭流泣的抱怨:「客户在不停地改需求」。这总是让我感到很奇怪,我所奇怪的是,
所有的人都对需求变更感到惊讶。我从来没有遇到过一个真正的项目,它的需求从不改变。即使你让
用户在需求文件上用血来签字,不管他们是什么血型,最终还是会改变。

用户改变他们的想法有下面几个原因。一个原因是:一个要开发的系统,将会是个什么样子,要具体
形象地表示出来是很困难的。只有当它摆在你面前,你去用它做实际工作了,你才会发现什么功能是
真正有用的,什么功能是没用的。另一个原因是业务变更,六个月以前还是一个很真实很重要的需求
,因为业务变更,现在就可能成为一个次要的需求。更另人恼火的是,有的用户自己也写过一些小程
序:这里用 VB 写过一点,那里用 Excel 宏(macro)写过一点,所以他们就认为软件修改很容易(而
他们从来也没处理过一个有许多问题,互相依赖的真正系统,但职业程序员必须处理)。

对许多人来说,这是需求工程必须面对的问题。我们需要更善于在事先把需求搞清楚,把更多的时间
花在弄清需求上,而且要跟上新技术的发展。我也曾经这样相信过,但是现在我得出的结论是:这是
不可能达到的,至少在一段时间内。

还有另一个关键的问题,这里需要取得一个平衡,你想要什么,你准备花多少钱。如果你买一台汽车
,汽车销售人员跟你说:「你要汽车顶棚吗?」,那么你要问的第一个问题可能是:「多少钱?」,
如果是 20 块钱,那么给我一个好了,如果是 20,000 块,那我宁肯不要。所以,除非我们给出一个
较为精确估价,否则客户是不可能把需求固定下来的。不幸的是 ,我们在估价方面表现的很糟糕。我
并不认为,这是由于软件开发人员都很笨的缘故,问题是我们用的基础材料在不停地变化。如果混凝
土的特性每年也都会『升级』地话,土木工程师们,亦会发现他们的估价也很困难。

那么有其它选择吗?我想有一种选择,它可以归结为:期待需求变化,采用一种欢迎变化的开发流程。
这种做法,与预先设计的核心思想格格不入。如果需求可以在没有任何警告的情况下改变,那么,让
我们怎么来做一个稳定的预先设计呢?

让改变更容易 解决办法是使建造的软件在面对始料不及的变化时,更能应付自如。(我们可以在设
计的时候,让它能够处理一些可预料的变化,但问题是那些不可预料的变化,跟在你的屁股后面咬
你。)对象技术是这里的一个关键。利用对象封装性(encapsulation)和多态性(polymorphic)的接
口,我们可以提高软件的组装特性,从而减少相互之间的依赖性,使改变也更容易。

动态开发环境也很有帮助,例如:对象浏览器,快速的找到交叉引用的特性,让你能探查你的代码
的除错器和监视器,很短的编译/连接周期。对于许多职业开发者来说,这些工具还很新,但任何一
个 smalltalk(译注:一种动态语言)程序员都知道:一个是在 debug 时,可以更改代码而且立刻
生效,一个是让编译/连接来打断你的注意力,这两者是多么不同。

Refactoring(译注:重整,不知道这个译法是否正确,它是指这样一种程序更改:代码更改的目的
不是为了增加功能,也不是为了提高效率,而是为了程序结构更合理,代码更清晰,可读性更高,更
易扩展。作为一个黑箱来说,程序没有任何改变,作为一个白箱来说,程序的确改变了)在这里也扮
演了一个很重要的角色。Refactoring 是这样一套技术,它可以有效地改变你的软件设计,却不会引
入新的 bugs。有了 Refactoring,如果一开始设计有错误,以后你去改掉它,就不需要花很大的代
价。

动态设计 所有这些技术(译注:上面提到的对象、动态开发环境、Refactoring)一起导致了我们设
计方法的转变,这种转变的方向,我把它叫做动态设计。在动态设计中,你用不着非得一开始就要设
计得完全正确。这并不是说让你放弃预先设计,你仍旧需要做预先设计,但这时,你设计的目的不是
找到最佳解决方案,而是找到一个合理的解决方案即可。你知道,当你开始建造你的软件时,随着理
解的一步步深入,你将意识到最佳的解决方案,与你最初的设想是不一样的。有了 Refactoring、对
象和动态开发环境,这将不是一个问题,因为改变已经不再昂贵。

需要强调的是,这种转变的重要结果,是导致了一场简单设计(译注:简单设计基于这样一种思想:
往一个简单的东西上面加东西,要比从一个复杂的东西上面减东西,容易得多。这也是 XP 的价值观
之一)的运动。在我用动态设计以前,我总是在寻找灵活(flexible)的解决方案。对于任何需求,我
总是想知道在系统被应用的生命周期中,需求会有怎样的改变。因为更改设计很昂贵,所以我试图让
我的设计,可以容许我能预见到的改变。

构建灵活方案的问题是灵活的代价。灵活方案要比简单方案复杂,通常来说,由灵活方案建造的软件
也更难维护,当然,如果恰好在我预见的方面需要灵活,那改变会更容易。所以,你需要懂得怎样去
让设计具有灵活性。如果只有一两个部分,那没什么,但如果整个系统都会改变,那可就麻烦了。让
整个系统在所有地方都很灵活,会使系统更复杂,维护的代价更高。

当然,更另人泄气的是,所有的这些灵活性,或许根本就是不需要的。也可能有一些是需要的,但让
你去预见到底哪一些是需要的,几乎是不可能。所以要得到你需要的灵活性,你必须加进一些你根本
不需要的灵活性。

用了动态设计,再去处理这些变更的风险,就大不相同了。你仍旧需要考虑潜在的变更,你仍旧需要
考虑灵活方案,但在决定采用灵活方案以前,你要问一问你自己,「把一个简单方案,变成一个我需
要的灵活方案有多难?」,如果答案是「小意思,很容易」(大多数都是这个答案),那么,你就采
用一个简单的方案去吧。

所以动态设计会导致简单设计,却不会损失灵活性。这也使得设计过程更简单,压力更小。一旦你理
解了这些东西,就会很容易的去重整(Refactor),你甚至不再去考虑灵活方案。如果需要改变,你
有信心去重整(Refactor)。就像 Kent Beck(译注:《Extreme Programming Explained》和
《Planning Extreme Programming》的作者)所建议的那样,建造一个最简单的东西,只要它能工作
。为了灵活而做的复杂设计,在大多数情况下,是不需要的。

这真是设计流程的一个大变革,而且对于我这样一个设计者,也需要一个很大的转变。但它有几个前
提条件:你需要很好的测试,你需要对象技术,你需要懂得Refactoring。不过它的回报也很丰厚,
你再也不用害怕需求更改了,还有你可以响应你客户的要求,而不必牺牲你的设计,甚至你的前途。

原创粉丝点击