No Silver Bullet - Essence and Accidents of Software Engineering - Brooks
这篇文章介绍了软件工程中面临的两类问题,一种是外在的易解决的(accident),另一种是内在的难以解决的软件工程与生俱来的固有困难(essence)。前者是实现软件设计中遇到的困难,后者是软件设计本身,之所以说没有对付软件设计这头猛兽的银弹,是因为软件设计具有如下几个特征:
- 复杂性(complexity)。软件工程没有办法应用建模的方法来抽取复杂度从而简化设计流程,因为复杂度是软件设计的必要属性。复杂度使团队成员之间的沟通、列举和理解所有可能的状态、函数调用以及在不产生副作用的情况下用函数对程序进行扩充变得十分困难,导致了程序难以使用、产品瑕疵、成本超支和进度延迟,影响了产品的可靠性。
- 一致性(conformity)。因为是开发最新的软件,所以它必须遵循各种接口。另一些情况下,软件的开发目标就是兼容性。在上述的所有情况中,很多复杂性来自保持与其他接口的一致,对软件的任何再设计,都无法简化这些复杂特性。
- 可变性(changeability)。软件产品扎根于文化的母体中,如各种应用、用户、自然及社会规律、计算机硬件等等。后者持续不断地变化着,这些变化无情地强迫着软件随之变化。
- 不可见性(invisibility)。软件的客观存在不具有空间的形体特征。因此,没有已有的表达方式。
文章中回顾了软件领域最富有成效的三次进步,首先是高级语言(High-level languages)带来的方便性,高级语言给软件开发者带来的便捷式显而易见的,软件开发者不用再去关心低层的实现而只要在一个抽象的(相对与计算机)但更接近人类思维的层面上去设计软件;其次就是分时(Time-sharing),只要分时的频率足够大,在人类分辨能力之上,那么就能取到很好的效果;最后是统一的编程环境(Unified programming environments),统一的编程环境是的软件开发者都使用统一格式,这样便于软件工作者之间的交流。但是每一次进步都只是解决了软件构建上的困难,但是这些困难都不是软件工程的本质属性,不是主要困难。除了这三次进步,文章还介绍了ada高级程序设计语言、面向对象方法、人工智能和专家系统、自动编程、图形编程、程序验证、环境和工具以及工作站等目前的研究进展,但作者都认为这些并不能够减小软件开发的复杂度。最后,作者提出了自己的看法,他认为购买有专业团队开发和维护的软件是减小软件设计中的困难的好方法,提出要从快速原型开始进行产品迭代过程,并强调了优秀的设计者对软件的重要性。
There Is a Silver Bullet – Brad J Cox
作者认为复杂结构的内部封装可以使软件变得简单易用,封装好的软件如同芯片一样,接口标准统一,人们不需要关注软件的内部结构,而可以专注于软件本身的使用和买卖上,可以建立这样的软件零件市场。
big ball of mud
大泥球,意大利面条式代码,代码的杂乱无章,随意堆砌拼凑,会产生不少错误或代码缺陷。程序员总是在方便修改的地方写入一些一次性代码来修复bug,虽然方便快捷,但是这样会为后续程序的修改产生其他bug隐患,当系统越来越复杂,这样的隐患累计起来就能形成大泥球了。
避免大泥球是需要我们去注意的地方,程序员和设计师应先关注软件的特点和功能,然后再关注构架和展现,设计初步避免产生小的问题或者方向的偏差。编写软件时要及时的解决出现的小问题或者原型概念,及时处理用户需求的变化。
我们的软件虽然规模不大,但是也有类似的“小泥球”,由于我们在编程过程中借鉴了上届学长们的可以使用的部分,而没有彻底地对一个功能或模块进行封装,导致有一部分代码结构很混乱,为接下来的开发埋下了隐患,我们打算在下一个版本中对这部分代买进行重构,并进一步封装已有的功能模块。
CatB – Cathedral and the Bazaar
大教堂和集市代表两种不同的自由软件开发模式,大教堂模式的每一个版本由一个团队掌控,集市模式则是完全地在互联网上公开代码,我们队的模式应该是属于大教堂模式,每个人的任务是根据模块进行分配,彼此间耦合性小,每个人都要对自己的代码负责,整体上整个团队掌控着软件版本。
Lost in CatB.
在使用开源代码方面,我们选择了经过网友们亲身使用,代码质量高的模块(这部分开源代码也是只有一个团队或个人维护的,应该也算大教堂的产品吧),没有出现质量缺陷等问题。
Worse is Better – Richard Gabriel
质量不一定随功能的增加而增加,精简、实用的软件往往能够获得更大的市场,吸引更多的用户。
Managing the development of large software systems: concepts and techniques
瀑布模型,项目开发架构,从系统需求分析开始直到产品发布和维护,每个阶段都会产生循环反馈。
定义阶段,可行性研究和需求分析;开发阶段,设计、编程、测试;维护阶段,运行维护。
用工作的顺序将问题简化了,将功能实现与设计分开,方便分工协作,将软件项目生命周期划分为制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动。当前一阶段完成后,您只需要去关注后续阶段。
Agile Method – by Martin Fowler
敏捷开发方法相对于传统的软件开发方法的一个明显的不同就是敏捷开发是与代码为主的,强调代码是文档的主要部分。相对于传统的软件开发方法,敏捷开发方法有以下的特点:
(1)敏捷开发方法是适应性比预见性更重要;
(2)敏捷开发是以人为本而不是以项目为本。
敏捷开发方法之所以提出适应性比预见性更重要是因为需求的变化往往是不可预见的,因此强调软件开发要有很好的适应性,预见性显得不是那么重要;作者在文中 提出的解决的方法是迭代(Iterations),利用迭代控制不可预见的过程。敏捷开发中提出把人放在首要位置,但是可能会遇到一些问题,但是作者给出 了相应的解决方法,作者提出了程序员要对自己设计的模块负责,描述了管理以人文本的项目的方法,并且提到了商业领导的职责是什么。
敏捷开发过程往往是一个自适应过程,要不断的在需求的变化下有一定的适应能力。下面作者就提到了一些比较流行的敏捷开发方法:
- XP(Extreme Programming)。XP是一个轻量级的、灵巧的软件开发方法;同时它也是一个非常严谨和周密的方法。它的基础和价值观是交流、朴素、反馈和勇气;即,任何一个软件项目都可以 从四个方面入手进行改善:加强交流;从简单做起;寻求反馈;勇于实事求是。XP是一种近螺旋式的开发方法,它将复杂的开发过程分解为一个个相对比较简单的 小周期;通过积极的交流、反馈以及其它一系列的方法,开发人员和客户可以非常清楚开发进度、变化、待解决的问题和潜在的困难等,并根据实际情况及时地调整 开发过程。
- SCRUM。Scrum是一种迭代式增量软件开发过程,SCRUM方法论中其核心仍然迭代和增量,首先对于产品需求会划分为多个迭代或增量,每个迭代都需要在1个月能够交付,而一个月即是一次冲刺,而一个迭代版本又需要转化到每天的进度跟踪和问题解决。
- Crystal Methods。把开发看作是一系列的协作游戏,而写文档的目标就是只要能帮助团队在下一个游戏中取得胜利就行了。水晶方法的工作产品包括用例、风险列表、迭代计划、核心领域模型,以及记录了一些选择结果的设计注释。
- 上下文驱动测试。以测试驱动开发也是提高软件项目适应性的一种方法。
- 精益开发。
- 统一过程。软件项目最后肯定是要将各个模块组合起来的,敏捷开发最后也需要一个理性的统一过程;当然这样是用例驱动的过程。
Extreme Programming,scrum,crystal methods都在我们团队开发过程中使用过。
软件工程的方法论到底有多少用处?
按照No Silver Bullet中的观点,软件工程的方法论也无法简化软件开发本身的复杂度,但是,软件工程中提到的方法的确能够令软件开发变得有条理,尤其提高团队开发的效率。其实,不止是软件开发的复杂度难以减少,很多方面的问题的复杂度都很难降低,比如npc,难道对于这类问题的不改变其复杂程度的优化都是没有意义的吗,显然不是,芝加哥大学的拉斯洛鲍鲍依提出的图的同构算法依然能够令学术界炸锅。所以,我认为软件工程的方法论在软件开发中还是能够起很大作用的。
在此版本开发中的感想
1.1+1<2,我们负责开发北航mooc客户端,服务器是由北航mooc网站的开发团队提供的,为了获得服务器的接口,我们花了将近两周的时间,我深深感受到耦合性给团队开发带来的阻碍。
2.少而精强于大而全,在alpha版本中我们原计划还要实现视频下载和学习进度管理两个功能,在与北航mooc课程网站负责人沟通的过程中,他劝告我们应该做一个简单能用的软件而不是功能全面而不好用的软件,我们也感觉到在alpha版本中做一个稳定可靠的核心功能能够为以后的迭代打下良好的基础,这也算是实现了《没有银弹》中提到的从产品原型开始进行迭代的设计思想吧。
3.团队分工很重要,每个人都应该对自己的代码负责,应该用到契约编程的思想。