一.阅读作业
1.关于“银弹”
所谓的没有银弹是指没有任何一项技术或方法可使软件工程的生产力在十年内提高十倍。由于软件创作包括了本质性工作和附属性工作,前者是创造抽象出复杂的概念结构,后者则是用编程语言来实现这些抽象出的实体。该篇文章的作者认为附加性工作的困难会随着工具的改善而逐渐改善,反而本质性工作的困难难以得到有效解决,因为大部分的活动是发生在人们的脑海里,缺乏有效的辅助工具,故抑制了软件工程的生产力的巨大提高。
在我看来,这一结论有些过于绝望,我觉得目前的一些设计方法和开发手段很好的改善了本质性的工作,使我们能够更加接近认识问题和解决问题的本质。比如:
(1)在设计小学生计算器时,采用的面向对象的思想,将计算功能,生成表达式的功能,检验的功能封装成了不同的对象或模块,这种高内聚低耦合的做法,使一个复杂的程序变得层次化,在设计时不在是面对整个层次的开发,而是针对不同模块的功能进行设计,大大降低了本质性工作的复杂性。
(2)采用增量式开发,在core模块编写时一开始只添加了加减运算的功能,后来又对乘除功能进行了添加,这种循序渐进的持续性的开发方式,也大大降低了设计之初的复杂性,后期逐步完善,最终开发出满足需求的软件产品。
故,以上这些方法很好的辅助我们进行软件的设计与实体的抽象,也大大降低了本质性工作得难度,提高了开发速度和开发质量。
2.关于“大泥球”
大泥球是指一个随意化的杂乱的结构化系统,只是代码的堆砌和拼凑,往往会导致很多错误或者缺陷。主要的原因有:一次性代码,碎片式增长,缺少前期设计,应对需求和架构变化过晚,缺乏经验和技巧。
在团队项目中,我是负责后端的实现工作,后端在实现上并没有出现这种大泥球的现状,我觉得我们通过以下几点避免了这种随意化的杂乱的情况:
(1)主要原因是后端采用rails提供的框架进行敏捷开发,rails的MVC架构将后端清晰地分成了三个部分,view层存储前端的界面代码,model层进行数据库的实现,controller层实现相应的action用来处理不同的请求。这样的架构体系使后端的开发层次化,降低了代码的复杂度和冗余的情况。而且对于后期关于数据库的一些属性或操作的修改,我们并没有直接去修改model层的代码,而是使用数据迁移的方式,并且标明了每次迁移要做的操作是什么,保持了程序结构的清晰和简洁。
(2)前期设计比较充分,在码代码之前,先是详细的列出了软件的需求及要实现的功能,根据这对后端进行了详细的设计,包括数据库设计中,每个实体的属性有什么,实体间有什么联系,属性的限制条件是什么,以及画E-R图,还有api的设计,路由该如何匹配,控制器有什么动作。这一系列的设计工作保证了我们程序的正确性,而且后期需求上发生一些微小的变化时,只需要简单的改动就可以解决。核心的设计并没有大的修改。
(3)代码复审:由于后端是三个人进行编写的,分别实现不同的api功能,在后期api进行调整时,确实出现了这种碎片式增长的情况,为此我们有代码复审这以环节,两个人一起对代码进行整体审核,统一规范三个人写的代码,并且对那些不好的实现做出相应的修改。
3.大教堂&市集
我们的团队项目采用的是大教堂的开发模式,项目开发是在自己租的服务器上进行编写的,别人没有服务器的帐号密码,自然不能对源码进行修改。根据老师的要求,我们将代码迁入服务器中,供别人查看,但控制权还是归我们团队所有。
将源码公布出来,可以使错误无处遁行。相较于市集模式,大教堂模式的开发过程中有很大一部分时间都是在找bug和修改bug,因为只有开发者才能进行修改。比如,在个人项目的编写时,800行的程序,里面有大量的逻辑判断和分支判断,即使写测试程序,覆盖所有分支,也不能保证自己的程序没有错误,况且写测试程序也是需要花费不少时间的工作。而市集模式则相反,大大提高了找错和除错的效率。但是这样做的不足在于,你很难保证你代码修改的质量,因为修改代码的人水平参差不齐,修改的错误也是有对有错等等,这就有可能使你代码质量下降。
就拿软工的的项目来说,比如向“学霸”这类的项目迭代了好几年了,一拨人在上面修修改改,再换一拨人继续修修改改,由于不同的人有不同的需求,不同的人设计的理念可能和之前的人完全不同,这种叠加式的开发,你会发现包越来越多,有些包与包之间不能直接互通,要通过别的包来统一接口,导致程序结构复杂,根本看不下去。最终,你决定,上一届写的太渣了,我们重构吧(重写),这样的集市模式开发的程序会导致结构更加复杂,程序难以维护和扩展。这也是我们组当初选择自选项目,而拒绝做老师提供的项目的一个原因。
所以针对于这两种模式的选择,应当做一些权衡。比如软工的团队项目,7个人一起的工程量还不是很大,所以为了开发软件的质量,我觉得大教堂模式应该是更好的选择。而且也可以综合起来应用,对于部分次要功能的模块可以进行市集模式的开发,对于重要的核心功能模块可以采用大教堂模式的开发。
4.Worse is Better
“坏点的更好”,强调的是简单压倒一切,为了简单性其他方面可以做出让步。简单性是指设计要简单,实现也要简单。为了简单性,正确性,一致性,完整性都可以做出一些必要的牺牲。一味的追求正确性,一致性,完整性可能会让你的程序变得很复杂,而你为这种复杂性所付出的代价,并没有给用户的体验的提升多少。
拿我们“北航社团平台”项目来说,我们一开始提出了很多的功能比如:网盘,商城,钱包,搜索,活动报名,社团推荐等等,但实际设计时,我们发现有些功能实现起来太复杂了,比如商城,钱包,搜索,为了程序设计的简单而又不影响用户体验,我们重点实现了社团活动展示和用户报名社团,通知用户这三个功能,因为我们这个平台建立的基本想法就是想给社团一个展示自己的平台,也是学生更加方便的了解社团的相关信息,这才是我们用户体验的重点。至于那些被cut掉的功能我们团队会考虑在二轮迭代的时候再进行考虑。
5.瀑布模型
瀑布模型严格把软件项目的开发分隔成各个开发阶段:需求分析,要件定义,基本设计,详细设计,编码,单体测试,结合测试,系统测试等。像流水线操作一样,把软件开发过程分成各种工序,对每种工序进行了更细致的分配。
它的特点:
(1)没有迭代和反馈机制,水流一泻千里,不可回头。如果开发的过程中,用户的需求发生了变化,或者是出现了严重的缺陷,不能很好的适应解决,甚至于重新进行开发。
(2)强调文档,瀑布模型当前阶段的输入来自上一阶段的输出,文档正是用于衔接的桥梁,开发人员根据文档进行开发,只有到开发的后期,才能看到软件真正的模样。
(3)流水线的开发模式,非常枯燥,不利于开发人员的创新,提高编程积极性。
6.敏捷开发
与瀑布模型不同敏捷开发的核心是迭代,最终目标是开发出让客户满意的软件,所以要能够主动接受需求变更,使设计出来的软件有灵活性,可扩展性。
相较于传统的开发方法敏捷开发是适应性预见性更重要,以人为中心,利用迭代来控制不可预见的过程。
我们团队项目的开发分为两轮迭代,第一轮迭代我们主要是实现基本的展示功能,并实现网站的后端框架和前端的几个页面。第二轮迭代打算增加更丰富的功能。开发之初PM为每一个人分配每天的任务和所需的时间,开发过程中每天完成一项任务,并将完成的任务关闭。
采用的敏捷开发的方法:
(1)Scrum meeting
从第一轮迭代的第二周开始,我们团队每天都会进行scum meeting汇报,包括今天自己完成了什么任务,明天的计划是什么。并生成每天的燃尽图,显示整体项目进度。这样的做法可以监督每一个成员每天按时按量完成自己的任务,保证项目的整体进度。另外,在scum中会讨论一些自己遇到的问题,或者一些想法,大家及时进行交流,对一些具体的设计或者需求进行修改。
(2)极限编程
在后端数据库设计时,我和我们组的王开同学进行结对编程,一起设计数据库的相关实体的属性及实体与实体间联系,建立概念模型的E-R图。然后两人一起实现model层的代码逻辑,包括相应的数据验证,还有关联的声明。在这一过程中,及时纠正彼此的错误,并对之前的关联的设计进行修改,及时进行代码审查,保证代码的正确性。
二.团队项目一轮迭代收获
我们团队项目是“北航社团平台”,其中我负责的是后端的实现部分。
对于个人而言,自己学到了不少网站开发的知识,我们后端采用的是rails4.0这个框架进行开发,由于自己之前从来没接触过,这次相当于从零开始,主要做的内容就是数据库的搭建和api的实现。其中api实现这个方面让我最为印象深刻,开发过程中前后端是分别进行各自开发的,它们之间通过预先定义好的api来进行交互,但是由于自己在实现时,有时为了代码的简单性,会私自修改api的一些参数,但又没有及时更新api的说明。到前后端进行拼接的时候,由于前端不知道正确的api是怎样的,所以测试时出现了一些麻烦,前后端api的不统一,导致了测试时花费了比较多的时间。
对于整个团队的开发过程而言,也算是经历了一次完整的敏捷开发,虽然每天都会有任务,而且要进行scum meeting,但感受到了敏捷开发固有的灵活性和可适应性,在讨论中大家及时把发现的问题和想法提出来,一起交流解决,不但提高了项目开发的效率,也是开发的过程更加灵活,及时适应需求的变化。另外也意识到队员间的配合是极为重要的,以前自己总是单兵作战,这次后端是三个人一起负责,怎样分工,怎样配合显得尤为重要。一人独挑大梁的结果往往是耗费自己大量的时间与精力,而又达不到想要的结果,队友间的相互配合,及时纠正对方的问题,才是高效率团队的体现。
Anyway,当软件真正从无到有,一步步被设计实现出来时,自己的内心充满了一种满足与喜悦,我想这就是团队开发给予我们每个人最美好的礼物。