个人阅读作业2
在《No Silver Bullet - Essence and Accidents of Software Engineering》中,
布鲁克斯将软件开发的困难分为两类:
本质性(essence):软件本身在概念(conceptual)建构上存先天的困难;亦即如何从抽象性问题,发展出具体概念上的解决方案。
附属性(accident):将概念上的构思施行于电脑上,所遭遇到的困难。
而本质性的困难又分为以下4条:
复杂性(complexity):软件要解决的问题,通常牵扯到计算步骤,这是一种人为、抽象化的智能活动,多半是复杂的。
隐匿性(invisibility):尚未完成的软件是看不见的,即使利用图标说明,也常无法充分呈现其结构,使得人们在沟通上面临极大的困难。
配合性(conformity):在大型软件环境中,各子系统的接口必须协同一致。由于时间和环境的演变,要维持这样的一致性通常十分困难。
易变性(changeability):软件所应用的环境常是由人群、法规、硬件设备、应用领域等,各因素所汇集而成,而这些因素皆会快速变化。
随着开发工具的改善,附属性的困难已经逐渐减小,而本质性的困难却十分难以有效地解决。本质性的困难发生在从问题到具体的解决方案的过程中,这是一个与人类思维密切相关的过程,本身就复杂而抽象。而且开发软件还是一个多人合作的过程,这就进一步的增加了本质性的困难。
不过,《There Is a Silver Bullet》中提到,我们有办法显著地提升软件开发的效率,方法有可重用的组件,面向对象技术。它们有可能成功地简化软件开发的难度。
不得不说,以我目前的编程经验都能感觉到,面向对象等让编程清晰,可重用的方法确实能相当程度地简化本质性的困难。使用这种方法,能将问题拆分,从而令问题结构清晰化,而且可复用的结构可以让人不再拘泥于重复相近的问题。虽然构思最核心的解决问题的思路时的困难性依旧存在,但是我相信随着软件开发技术的发展,我们能最大限度地降低获取问题解决方案的难度。
读《Big Ball of Mud》的时候,真的是十分感慨,读出了许多我编程时常有的情况。仔细一想,我的程序也总是会不经意间变成那种“Big Ball of Mud”。在编程的过程中,如果程序的规模稍微大一点,我的代码就会不断堆叠,拼凑。想到这里就补一下这里,那里出错就改一下那里,结果把程序变得笨重而又漏洞频出。现在看来,我在编写程序的时候,确实缺乏一种整体的设计和明确的关注点,可能心里想的只是“怎么解决这个问题”。在编写程序之前,先好好考虑一下上层设计,确实是十分有必要的。把程序的框架搭好,才能让编出的程序规整又稳固,即使出错,也能在框架的范围之内解决,而不会留下隐患。
《The Cathedral and the Bazaar》中提到了两种开发模式:
大教堂模式(The Cathedral model)︰原始码在本模式是公开的,但在软件的每个版本开发过程是由一个专属的团队所控管的。作者以GNU Emacs及GCC这两软件为例。
市集模式(The Bazaar model)︰原始码在本模式也是公开的,不过却是放在因特网上供人检视及开发。作者以Linux核心的创始者林纳斯·托瓦兹带领Linux核心的开发为例,亦引用fetchmail的开发为例。
我们的团队使用的是市集模式,相信其他团队也会是市集模式吧,因为我们本来就是共同开发,相互需求代码,而我们拿到的代码也是从上一个团队那里接手的。这种开发模式确实存在着风险,不同的人,不同的团队对一个项目的开发就意味着有质量参差不齐和效果不尽如人意的可能性,其实这种可能性可能已经在软工课程的这几个项目应验了。就我们的“学霸”网站项目来说,接手这个项目的上一届学长真的就非常神奇地把上上届学长开发的网站“完善”出了很多问题,甚至网站的一些重要功能都无法正常运行。可见,如果想要将“市集模式”高效高质量的实行,还是需要团队之间的有效沟通和对项目负责的态度。如果找不到沟通的机会,那么接手项目的人只会一头雾水,即使他有足够的能力,足够的时间去理解代码,他的开发也不会和这个项目的最优发展方向重合。这样的效率和效果相信也是任何人都不想要的。而没有责任感,一切更是无从谈起。
《Worse Is Better》中,我们看到了Richard P. Gabriel 先生对于软件工程各个因素的优先分级:
简单性:设计必须简单,这既是对实现的要求,也是对接口的要求。实现的简单要比接口的简单更加重要。简单是设计中需要第一重视的因素。
正确性:设计在任何值得注意的方面都要求正确。为了简单性,正确性可以做轻微的让步。
一致性:设计不能过度不兼容一致。为了简单,一致性可以在某些方面做些牺牲,但与其允许设计中的这些处理不常见情况的部分去增加实现的复杂性和不一致性,不如丢掉它们。
完整性:设计必须覆盖到实际应用的各种重要场景。所有可预料到的情况都应该覆盖到。为了保证其它几种特征的品质,完整性可以作出牺牲。事实上,一旦简单性受到危害,完整性必须做出牺牲。一致性可以为实现的完整性作出牺牲;最不重要的是接口上的一致性。
我在编程的时候的优先级却是:一致性最重要,其次是完整性,再其次是正确性,最后才是简单性。我总是想让一种模式完全地去匹配一个问题的解决方法,而且还想要覆盖所有情况,只要匹配上了而且覆盖到了,我就觉得差不多正确了,至于简单之类我真的没太大追求。
看了这篇文章里的优先级后,最开始就是觉得很有趣,简单居然比正确还重要!而且完整性居然是最后一位要考虑的。
不过我想把简单性放在第一位一定是一种十分高明的做法吧,我能隐约地感觉到简单性里说不定还蕴含着其他三项的一部分。而且,动脑和动手是有区别的,很多时候你不把事情简单化的话,可能事情的主次先后都会混成一团,哪有什么先后。这么考虑的话,这种优先级还是十分值得借鉴的。
我们的团队在开发的过程中,采用了结构和细节上的分工,在开发和管理的层面上也有分工,但是可以肯定的是,这种模式还有许多值得改善的地方,无奈时间实在是不够充裕,大家都忙得不可开交,我们可能并不能来得及做这种调整和规划。
我相信软件工程一定是要遵循一定的方法的,有理论,有结构,有预见性的开发过程能带给开发者和产品的好处不言而喻。我尊重并支持软件工程的方法论。