前言
一个学期,两轮迭代的软工、数据库课程设计、编译课程设计,还有一些有的没有的小项目。似乎这四个月的时间完全付诸于开发了。每天工作小时数是两位数,总计上万行的代码量,这一个有一个数字无一不在帮助我们提高这自己的编程水平和开发能力。
或许是时候做一个总结了,总结一下一个学期下来的收获,也会为一下这一段时间以来的艰辛与快乐。
两阶段开发总结
经过一个学期的努力,我们的项目完成了M1和M2两个开发阶段,发布了alpha和beta两个版本,其中alpha版本实现了主要功能,二在beta版本的开发过程中,由于需要多组间合作,因此我们对上一个版本进行了重构。从环境搭建,到新技术的学习,再到代码实现,进而测试、发布,我们经历了重重困难才最终发布出来这个网站。
与其说是总结,不如说我更想谈一谈在开发阶段出现的想法。
首先让我印象最深刻的是M2的重构。在M2阶段,我们为了和客户端组公用后端,我们把原本的使用跳转的网站改造成了单页应用,其中引入了ReactJS。又一次引入新的框架,这显然让我们感觉到有点吃不消。新的框架采用了数据单向流动的思想,形成了自己独有的一套体系,直接限制了jQuery的使用,导致大量的代码需要修改才能使用。为此我们讨论了很久。但是经过一段时间的努力,我们的代码成功迁移,新的框架顺利部署,这让我们的信心大增。
让我印象最深的第二点在时间的分配。在M2开发阶段,我们同时要完成软工开发、数据库课设开发、编译课设的后期编码工作。几个大型工程同步开发,已经不满足系统的可调度性,那么要怎么做?刷夜!一周刷夜两天三天已经成为了一种常态,每天3点前想睡更是天方夜谭。每天的时间几等分,分别做不同的事情,坚决不浪费其中的每一点时间。经过很长一段时间的努力,我现在终于可以说,我们撑过来了,我们胜利了。这让我想到了真是软件开发中的发布前几天,如果此时真的没有完成工作,或是测试未通过,那么要怎么做?
Scrum Meeting,这是我们开发过程中每天或每两天都要进行的活动。每次Meeting过后,我们都会汇总工作进度,实现开发过程中人员的动态调配。这也多亏了我们有一个全栈工程师才能实现这样的调动。现在开发结束了,大概我们也只剩下最后一次Scrum Meeting作为庆功宴了吧。
经历了两轮迭代的开发,我对软件工程中的很多观点有了更深的印象,对很多问题也有了新的看法。
问题整理
曾经的问题
传送门:戳我进入
1.软件工程是一个在不断发展的方法学,随着时间在不断变化。那么我们现在学习的方法是否会被替代?如果会,原因是什么?
答:软件工程中的方法确实是在不断发展的,但是这个发展并不意味着彻底的推翻。我们在做项目的过程中,M1和M2阶段进行了两次重构,因为我们发现就在我们开发的过程中,已经有新的设计思想产生。但是重构并不意味着我们需要完全推翻已有的成果,而是修改掉与新的思想不符合的部分。软件工程亦是如此。新的思想产生势必会对老的思想产生冲击,但是两者存在的主要还是共性,因此可以说新的思想只是旧思想和方法的发展,并不会在很短时间内彻底颠覆。长远上讲,即使通过很多次思想和方法的演化,就得方法学消失的无影无踪,但是这其中的发展也是值得学习的,更何况我们不可能在如此长的一段时间之内完全不进行开发。再者言之,不同的方法针对不同类型的问题,因此方法之间想要真正实现完全的替代也是不现实的。
2.书中写,团队需要有明确的分工。但是对于我们这样的小团队,甚至是更小的团队,无法做到平均的分工,是否还应该有按照职责的明确的分工?
答:分工是要有的,即使并不能做到均分。撇开集市模式不提,对于一个任务型项目,分工显得尤为重要。我们都知道责任分散效应,如果一个任务没有明确指定完成者,那么所有人都不会采取行动,导致的直接结果就是项目不能完成。因此为了我们能顺利完成一个可靠的项目,分工是必须的。次之,分工有利于加快项目的完成进度,在我们进行项目的过程中就有体会。我们的项目前后端均使用了较为复杂的框架,框架的学习成本本身较高,如果不进行分工,每个人都接触所有的框架,那么项目进度将一拖再拖,完成的日期就没法预期了。但是对于小团队,我认为分工不一定需要非常明确,可以采用根据需求和实际开发进度调整的方式,动态调整,维护整体该法进度平衡。
3.既然短期刺激和长期影响并统一,那么在开发时怎样衡量和评估软件的前景?
软件需求可以分为多个层次:新鲜感、基本功能需求、特殊功能需求。新鲜感是指一个软件在发布过后可以吸引到的第一批用户所需要的资本,是我们能从表面上给别人留下的印象。基本功能需求是指基本所有使用用户都会使用的功能,如果我们连基本的功能需求都没有,那么必然不能留住用户。特殊功能需求是指我们有二别人没有的功能,软件需要靠满足特殊功能需求来从其他同类产品中吸引用户并留住用户。一个我们在软件功能设计的时候也需要考虑这几点。新鲜感主要依靠前端实现,需要前端有足够的吸引力。基本功能可以仿照其他网站实现。特殊功能是我们设计中着重考虑的部分,因此我们加入了很多自己的设计。一个软件的前景并不能很好估量,但是通过做到以上几点至少能保证不会很快的被排挤出市场。
4.为提升用户的第一印象,很多软件选择减少开启界面的复杂度,但是这样会掩盖很多软件的功能和特点。对于这一矛盾应如何抉择?
暂未解决。我们致力于通过显而易见的方式让用户可以发现我们的功能,虽然不在主页面上显示,但是从主页面找到任何功能的操作都不会非常复杂。
5.敏捷开发中,尽早持续交付是一个基本原则,而十五章又讲需要渐进发布,这二者应该分别用于什么场景?
尽早交付和循序渐进并没有矛盾。尽早交付只是意味着交付一个可以使用的版本,而渐进交付意味着不断添加功能。就像Windows10的更新方式,每次添加额外的功能而不是直接发布新版本。这种方式可以实现尽可能早的给用户他们期望的功能,用户也一定会根据先用功能决定是否继续进行项目,这是一个相互促进的过程。
6.如果开发过程中,用户的需求出现了较大变化,应选择重构代码,还是在现有基础上修改?
暂未解决。我们没有改动需求,只进行过两次重构,其中第二次是需求出现了较少变化。但是每次重构的工作量都不小。如果是需求发生较大变动,恐怕会不得不重构,是否能承担这样的风险就不得而知了。
7.书中对绩效的评定方式阐述的很含糊,没有给出一个可以量化的方式。在现实中绩效是如何考察的?
对于绩效的评定,没有一个确定的方法,不同类型的团队可以采用不同的方法。我们曾选用时间工作量综合量化加奖惩机制的方法。这种方法在开发过程中虽然起到了一定的激励作用,但是必然是不公平的。绩效的存在本身就是为了鼓励成员高效高质量完成工作,因此只要能达到这个目的,任何方式都是可以的。
###产生的新问题
1.当开发不能正常完成时,我们应采取什么样的措施?
2.在多组合作进行开发时,如果已经设计好接口,某一方发现需要额外的数据或需要调整接口设计,是否应当联系其他组进行修改?
3.在工作量难以预估的时候应怎样设计开发计划和进行人员分配?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~我也叫分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##软件工程收获体会
软件工程是一门实践性课程,在课程的实践过程中,我体会到了很多仅仅通过上课所得不到的东西。我还将其中的一些思想带入到数据库课设和编译课设的编码过程,发现确实对编码效率和质量有很大提高。以下是我感受最为深刻的几点:
#####1.结对编程
结对编程是我在这个学期体会最深的东西。在数据库课设开发的过程中,体会尤为明显。结对编程的核心思想在于一个人写代码,一个人指到思想,同时指正代码中出现的失误或错误。在一个人编程时,由于手误导致的错误频发,这类错误难于调试,总是出现在非常隐蔽的位置,在debug的过程中总是会花费大量的时间。在结对编程的模式下,由于引入了一个一直在关注屏幕而不是键盘的人,这类错误的出现概率明显降低。除此以外,结对编程还有利于发现逻辑上设计的失误,有利于一遍写出高质量的代码。
#####2.架构和设计的重要性
编码速度和质量会对一个软件最终成型的效果产生较大影响,但是这个影响远远不及前期的架构选择和设计。我们在M1阶段使用了Semantic UI + Django的架构,在第二阶段为了实现单页应用又引入了React JS。这一套架构的选择直接为我们省去了很多基础性功能实现的编码时间。
软件结构的设计也是十分重要的。在我们的开发过程中,最重要的就是数据的传递。我们拥有大量的数据,这些数据要在多组之间共享。因此我们需要制定好接口,确定哪些数据在前端处理,哪些数据在后端处理。M1阶段我们没有清楚地划分界限,在M2阶段就不得不进行重构,重新定义接口规范,修改前后端的中间件和数据处理模块。
#####3.软件开发的六个阶段中的知识点
软件开发分为六个阶段,需求/设计/实现/测试/发布/维护。
+ 分析:结构化需求分析和面向对象需求分析,二者相互辅助,共同决定一个软件的设计功能需求。
+ 设计阶段:软件结构设计、数据格式设计、接口设计共同决定了软件的流程,在每个流程中还要设计各个过程从而真正实现一个软件。设计是要遵循高内聚、低耦合的设计思想。
+ 实现阶段:可以采用结对编程的形式提高编程效率。每一处代码需要有单元模块测试,迁入时需要进行复审。
+ 测试阶段:主要测试模块间的耦合关系。可以选用人工测试的方法,也可以使用脚本测试。背刺软件重新编译后,都需要进行回归测试来保证没有破坏更改前的功能。测试可以选择白盒测试、灰盒测试或黑盒测试,但是需要尽量保证覆盖代码段中的每一条语句。
+ 发布阶段:软件正式上线。此后需要不断收集用户反馈的信息,维护软件功能,修复bug。
+ 维护阶段:维护阶段持续时间最长,维护的成本很高。所以在实现阶段就需要考虑到可维护性,不能滚泥球!