现在的位置: 首页 > 综合 > 正文

论软件的复杂性

2013年02月20日 ⁄ 综合 ⁄ 共 1471字 ⁄ 字号 评论关闭

目前软件所采用的体系结构相对要解决的问题来说,不管要解决的问题本身是简单还是复杂,软件给出的解决方案通常都不会简单,尤其是一些企业级解决方案。

软件是用来解决问题的,如果问题域本身已经很复杂,再使用一个更加复杂的工具去解决它,其成功的概率为0。关于问题域的复杂性可以参阅布鲁克斯那篇“没有银弹”的经典文章,本文关注的是软件的复杂性。

从软件的发展历程看,复杂系统通常都会失败,不过失败后都通常会衍生出一个相对简单而实用的系统。这些复杂系统初始的目标看上去都很完美,可以被当成万能药使用,因此其实现通常都会比较复杂,难以学习,难以使用。这时一些实现相同目标的相对简单的系统就会出现,虽然这些简单系统有一些缺陷,但其实用性很强,通常比其复杂的前辈更能得到推广。 下面的例子充分说明了这点:

为简化MULTICS而诞生的UNIX已被广泛使用了30多年,再继续用上30年应该也没问题。 UNIX的核心思想就是保持简洁性。(参见 Eric S. Raymond   The Art of Unix Programming)

目前在Internet上广泛使用的TCP/IP协议是从一个叫OSI (Open Systems Interconnection)的模型简化后得到的。在OSI模型中,网络被分成了7层,而不是TCP/IP的4层。实现一个7层的协议要比4层协议困难得多,虽然也有7层的实现,不过由于其bug太多,最终被实现相对比较容易的TCP/IP所替代。

针对J2EE复杂性而出现的轻量级解决方案如Spring、Hibernate、Ruby On Rails等。

再举一个mail的例子,现在使用的SMTP和POP3有很多设计上的缺陷,导致存在安全隐患和垃圾邮件横行,但相比复杂的X.400协议,SMTP和POP3实现要简单很多,而且大部分情况下是可以满足用户发送邮件的需求的。所以现在很少见到X.400。

软件复杂性产生的原因大致可归结为以下方面:

  • 追求完美,想发明“银弹”。希望系统能对要解决的问题给出一个完美而通用的方案,因此就将所有可能的情况都加入到系统实现中,使得系统变得复杂,庞大。如MULTICS、CORBA、OSI等, 从实践看,这样的系统通常不会有很长的生命力或得到广泛应用。

 

  • 系统使用过程中逐步变得复杂。 系统初始设计时吸取前车经验,会比较简单,但随着使用者的增多,新的需求也不断提出,另外还要在竞争中保持优先,新特性会不断加入系统,使系统变得复杂。Java就是个例子,刚诞生时对C++作了很多简化,很快风靡软件界。 但到了10年后再看Java,当初简化掉的特性基本都已加入系统。 Java的这种复杂性使得一些相对简单的动态语言红极一时。

 

  • 利益驱使或个人表现。 不把系统搞得复杂一点不能够将价格抬上去,另外将系统搞复杂一点可以让人不能一下看出其深浅长短,以显得高深莫测。

 

软件复杂性带来的危害:

  • 增加开发难度,降低开发效率。 开发一个复杂的系统需要耗费不少精力去应对复杂性本身所带来的附加工作量,不能有效关注在解决问题本身,造成开发效率的降低。

 

  • 增加维护难度。 维护一个复杂系统是一个很艰巨的任务,你需要时刻防备系统不稳定性造成的故障。当要扩展系统时,其复杂性将成为一个需要花大力克服障碍。

 

  • 增加学习使用难度。复杂性会使学习曲线变得陡峭,如果封装得不好,会对操作带来很多的不便,通常需要花费很多的时间才能掌握其操作。

图灵奖得主、QuickSort算法的发明人霍尔曾说过,开发软件有两种方法:一种是使系统尽可能简单,使它看上去没有什么缺陷;另一种是将系统弄得很复杂,使你很难看出它有什么缺陷。

抱歉!评论已关闭.