您的位置:首页 > 其它

软件质量需求

2005-04-05 13:35 363 查看
Bertrand Meyer 和 Bill Venners 讨论软件质量不断攀升的重要性、市场对软件质量的影响以及软件复杂性的挑战。
Bertrand Meyer 是同时活跃于学术和商业二界的软件先驱。他目前担任瑞士理工学院的软件工程协会主席。他撰写了数量浩繁的论文和书籍,如经典的《面向对象软件构造》( Prentice 出版社, 1994 , 2000 )。 1985 年,他创立了交互软件工程公司。公司目前已经更名为 Eiffel 软件公司,提供基于 Eiffel 语言的软件工具、培训和咨询业务。
2003 年 9 月 28 日, Bill Venners 对 Bertrand Meyer 做了电话访谈。在这次访谈(内容将在 Artima.com 分多次公布)中, Meyer 对许多有关软件的问题作了鞭辟入里的论述,如软件质量、软件复杂性、契约设计以及测试驱动型开发等。在这个最开始的部分中, Meyer 论述了软件质量不断攀升的重要性、市场对于软件质量的影响以及软件复杂性的挑战。
软件质量的重要性
你在 2001 年 InformIT 对你的一次访谈中讲到:“当前的形势很好,以至在软件界,质量已经能成为很多人的话题。它将日益成为人们最主要的议题。”这是为什么呢?
计算机的应用已经遍及社会生活的方方面面,因此,质量低下的软件是不被接受的。软件业飞速发展,我们对软件的依赖性也日益增加。到了今天,我们必须面对一些由来已久但不被重视的问题。
Alan Perlis 在麻省理工学院的一本教材—— Abelson 和 Sussman 合著的《计算机编程的结构和解析》——的序言中有一段颇具启发性的话。他写到:
我认为计算机科学至关重要的是保持“计算”的趣味性。在它刚兴起的时候,它的确非常有趣。当然,用户也常常为之买单;过了一段时间,我们开始认真对待用户的抱怨。于是我们认为自己应该为计算机成功地、无错地完美运行负责。我却不这样看。我认为我们应该为之努力的是延伸计算机的功能,让它们有新的发展方向,让我们的屋子里充满趣味。
一种典型的态度是:“你完全可以相信,我们能做任何我们想做的事情。如果有什么问题,我们会修正它。”但这恰恰已不再可能。人们对软件的依赖性如此之大,以至他们根本不可能接受这样的态度。在 .com 时代( 1996 到 2000 年)的早些时候,这样的观念还勉强能站住脚,但到 1998 年已不可能。这种在过去可以让人们轻易接受的搭便车态度,如今已无立足之地。
2003 年 5 月,《哈佛商业评论》发表了 Nicholas Carr 的文章《 IT 麻木不仁》,文章指出: IT 没有兑现它的承诺。这发出了一个明显的信号:整个社会要求我们对自己的承诺要有比过去高得多的严肃态度。尽管在目前看来,我们似乎还能(不负责任地)搭便车,但这样的时代将很快终结。人们越来越关心我们的所作所为,关心自己的支出是否可以得到回报。这一些的核心就是质量。
市场对软件质量的影响
你的论文《可信任组件的巨大挑战》中谈到:“质量提升的动机是存在的,但它仅仅被允许到达这样的水平:可以存在在市场上不会危机到产品有效性的缺陷。大多数管理者认为超出此范围的质量提升措施只能产生急剧下降的投资回报。”那么市场到底是怎么影响软件质量的?
市场力量对于软件质量的影响,既有正面的,也有负面的。这差不多和里根经济政策时期流行的拉弗曲线理论类似。我不是经济学家,也听说这个理论目前已不足信,因此我没有暗示拉弗曲线在经济学上根本正确的意思。不过,拉弗曲线告诉我们,如果你按 0% 水平对人们征税,那么国家会遭受灾难,因为它得不到任何收入;如果提高到 100% (不能再高的水平),则人们不能获得任何收入,因此他们将拒绝工作,这样国家也得不到任何收入。这是一种相当单纯的讨论。尽管拉弗曲线在这一点上具有相当明显的合理性,但我无疑确定它在经济学上的正确性和精确性。不过作为一个类比,它可以很好地描述市场力量对于软件质量的影响力。
如果你的软件产品质量非常糟糕,你将得不到任何收入,因为没人愿意买它。相反,如果你穷尽时日、耗尽人力、物力和财力去构造绝对完美的软件,那么其过长的开发周期和高昂的成本将决定你必然退出市场。你不是错过市场机遇就是最终耗尽所有资源。所以,置身软件行业的人们都要努力寻找一个难以把握的平衡点:产品要足够好,以至它不会在诸如评估等阶段就马上被否定;同时也不追求十全十美、精雕细琢,否则会囿于时间和金钱而无法达到目的。
复杂性的挑战
你的大作《面向对象软件构造》中讲过:“可靠性,或许还有软件质量,的唯一最大敌人通常是复杂性。”对此你能展开谈谈么?
我认为我们的软件中存在一些到达人类想象极限的复杂部分,某些时候,这些部分让我们一败涂地。构建大型的、让人满意的系统的唯一办法是不要持续地复杂化,必须保持对复杂性的控制力。比如 Windows XP 系统包含大约 4 千 5 百万行代码,这完全不是单独某个人可以理解甚至想象的。如果要想保持对它们的控制,或者说还希望哪怕有一点点可靠性的话,唯一的办法就是剔除没必要复杂的部分,而想尽办法保持对其余部分的复杂性控制。
复杂性控制在 Eiffel 语言编程中是一个基本原则。 Eiffel 对人们作复杂、高难度开发大有帮助。当然,你可以用 Eiffel 语言构建简单的、困难适度的系统,甚至可以比使用其他工具做得更好,但当问题复杂到超过你的意愿,你没办法控制其复杂性的时候, Eiffel 才会真正大放异彩。例如,它的基本原则之一就是对对象模块性和隐藏信息要有相应的严格规定。在很多别的语言中,你能找到取得隐藏信息的简单办法,但 Eiffel 中是不存在的。一开始,这些严格规则可能会激怒程序员,因为他们无法干自己想做的事情,或者要写更多的代码才能达到目的。但当你需要拓展你原来的设计时,这些规则就成了避免大祸的强大卫士。
比如,在目前很多的面向对象语言中,尽管有一些限制,但你可以直接给一个对象的字段赋值: x.a = 1 ,其中 x 是一个对象, a 是它的一个字段。任何一个有近代方法论和对象技术基础的人都明白为什么这是错误的。几乎每个人都会说:“的确是错误的,但大多数情况下我不会在意它。我当然知道我在干嘛。它们是我的对象和类,我应该控制它们所有的访问接口,所以你不要来烦我。不要强迫我额外写些代码去封装对字段 a 的修改过程。”表面看,他们是对的。短期内,小范围情况下,它没有问题。有谁会在意它呢?
但直接赋值这样一个典型的小问题在你有上万、十万甚至百万行代码、有成千上万个类,很多人参与一个项目,项目经历很多变动、大量修改,并且需要面向不同平台的时候,会将事情带入一个完全不同的方向。像对象字段直接赋值这类问题,将彻底搅乱整个架构。最终,一个小问题要带来一个大麻烦。
如此一个小问题,你完全可以很容易在源代码中修正它。你仅仅需要像 Eiffel 语言那样禁止对对象字段的直接存取,转而必须在对完成这项工作的简单过程的封装基础上进行——当然这样的过程可能还需要一些契约。这是一个很容易消灭在萌芽阶段的问题,但如果你不这样做,它将会茁壮成长,最后置你于死地。
另外一个例子是重载:在同一个类中定义相同名字(的方法)去实现不同的操作。我知道对于这个问题是有争议的。人们已经被洗脑,坚信重载是一个非常好的东西,但本质上,它是危险的,并不是个好东西。和对象字段直接赋值一样,现在的各种语言都支持重载。人们编写的各种库中,重载泛滥,用一个名字(的方法)去实现许多不同操作。表面上,它短期内有其便利性,但长远来看,则付出了复杂性上升的代价,因为你必须搞清楚不同操作中每个变量的确切含义。其实,对象技术(当然还包括 Eiffel )中的动态绑定机制完全能提供人们想要的、比重载更好的灵活性。
所以说,有很多例子证明,如果在编程语言设计时谨慎一些,就可以大大趋近复杂性控制的目标。这可能有时候也人们为什么不相信我们有关 Eiffel 的承诺的原因。 Eiffel 的使用是非常简单的;我们公布的例子也很简单,但其原因并不在于问题本身简单,而是我们的解决方案简单。 Eiffel 其实是一个剥离人为的复杂并找到常常隐藏起来的、本质上的简单性的工具。但我们现在发现人们有时候并不相信这一点,不相信有简单的解决方案。他们认为不是我们隐藏了某些东西,就是这种语言和这些方法并不能真正解决软件开发中的实际问题,因为他们相信就是应该更复杂些。有如此一种可恶的陈词滥调:“如果它好得不像是真的,那么就必然不是真的。”这可能是人类有史以来最愚蠢的说法。很多人都有这种论调,但在 Eiffel 面前,它恰恰就错了。只要你使用正确的工具去解决问题,你就可以去除不必要的复杂并找到隐藏的、本质的简单。
任何一个正在构建大型系统的人,天天面对的中心议题就是:如何剔除不必要的、人为的、自找的复杂部分,并控制好剩下的、无可逃避的复杂性。在这个问题上,继承、契约、泛型以及面向对象开发等思想一般都可以——特别是 Eiffel ——发挥重要作用。
根据我的理解,你应该是在论述两件事情:去除不必要的复杂性和处理必然的复杂性。我可以找到一些工具,如面向对象技术和语言,帮助我们处理必然的复杂性。但是工具如何帮助我们去除自找的复杂性呢?你所说“找出复杂背后的简单”是什么意思?
我们来看现在的一些操作系统。例如,人们猛烈抨击 Windows 的复杂性,但我并不认为其他竞争者做得更好。人们并没有攻击任何厂商的需要,但是很明显,有些系统的确显得过于混乱。如果重新彻底地审视人们提到的某些问题,的确可以设计出更好的架构。但是从另一方面来说,一个操作系统的复杂性又是无法避免的。 Windows XP 、 RedHat Linux 和 Solaris 都必须处理 Unicode ,必须为上百种语言提供用户接口。特别是 Windows ,它必须兼容大量厂商生产的难以计数的不同设备。这就不是学术界批判的那种自找的复杂性。在现实世界中,我们不得不面对外界强加给我们的各种要求。因此,复杂性可以分为两类:必然的复杂性,它要求我们必须通过优化组织、分析隐藏信息和模块化等手段找到办法来处理;另一类是人为的复杂性,我们应该通过简化要解决的问题来消除之。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: