结对编程第三周总结
项目 | 内容 |
---|---|
课程 | 2021春季计算机学院软件工程(罗杰 任健) |
要求 | 结对作业-总结 |
项目地址 | 结对编程gitlab仓库 |
过程回顾与反思
在两周的结对编程过程中,我印象最深的有两个阶段:分析设计阶段和测试阶段。所谓说明书有多长,设计阶段就有多“痛苦”。你的设计有多复杂,测试阶段就有多“痛苦”。当然,这都是夸张的吐槽,但毫不夸张的是,我们组在这两个阶段上花的时间相比coding要多得多。
测试
实不相瞒,我在这一次结对编程前,对于测试这个阶段的工作,重视程度并不高。其实我早应该警醒,因为之前的好多作业(比如OO)都是因为测试不到位出错。或许是过于相信自己的逻辑,或许是偷懒,我在测试方面的工作做的并不好。
但是我的队友很好的弥补了这一点。这并不是因为每次作业覆盖率都要超过90的push,我的队友对于测试重视程度很高,即便是最简单的函数单元测试,他也会测上很多看起来很冗余的情况。(说实话,在这方面我还是抱了他的大腿)
测试程序应该覆盖每一个可达的分支
这是书上的一句话。我们在第一次作业很好的践行了这一点,几乎所有的语句全部覆盖了。唯一一条没有被覆盖的语句,是为了保险,加入的一个抛异常的语句。(其实这个语句根本无法到达,我们并没有删掉)但是我们确实做到了每一个可达的分支,可达的语句都做了测试。
第二次的作业,由于之前分析设计和coding的时间较长,我们的测试覆盖率刚好超过90。但是最终两次作业的强测都全部通过,第三次作业测试也只错了一个点。(错的这个点确实是分支没有覆盖到的地方)
这两周的结对编程我在真正体会到,测试对于一个程序的重要性,肉眼可见的重要性。
在编写测试的时候,我们也发现了大大小小的bug。有一部分是因为两个人对于细节理解的差异所造成的,还有一部分是因为测试程序逻辑写错(其实是测试程序的bug而非程序)。
覆盖率
我们在第二周ddl的时候,为了测试覆盖率能超过90绞尽脑汁。一切的一切都因为我们的设计在某些地方非常冗余。如果代码的耦合度较高,覆盖率高是件很容易的事。
我们的MyFileSystem类的设计就非常的冗余,即便每一个命令都有类似的解析地址这样的操作,我们也没有把他们单独提出来写成方法。我们考虑的初衷是,不同命令可能有不同的实现细节,那么如果利用耦合的思路,可能不太好考虑特殊性。考虑特殊性的代价,就是牺牲掉耦合度。同时,冗长的代码也让测试变得复杂冗余起来。我们的每一个命令都要写一堆重复的错误例子,才能很好地覆盖全部的分支。这对于耦合度较高的代码来说,一个测试就够了。
可是反过来想,测试程序多了,是不是更有利于我们去发现bug呢?虽然从覆盖率的角度上来讲可能不会,但是测试代码一多,我们自然的就会去考虑更多情况。或许是因为代码多,覆盖率上升困难,我们尽可能的考虑了各种各样的情况,所以两次强测都没有出bug。可能这就是“福兮祸之所伏”吧。(可是谁又不想代码简洁、耦合度高呢?)
无止尽的issue
哇,说到这个,真的是非常的佩服我们的助教团队。我能感觉得到,指导书都是经过反复斟酌,各种情况也写的很全。可是“人非圣贤孰能无过”,有的地方总会有差错和不解,这是不可避免的。很少人能够写出完全工整的指导书或需求书。
软件工程,唯一不变的是变化。所以干脆别幻想客户的需求会在第一时刻很明确,然后保持不会变。
我们也深刻的体会到了这一点。影响设计细节的往往是细节,有时细节甚至会影响到设计整体思路。所以在设计分析阶段,我们就曾因为很多不确定的小细节而被迫中断设计的思考。这让我们coding的节奏中断了许多次。
上课的时候,老师给我们举了一个很形象的例子:
一位顾客拿着一张大部分完整的发型照片找到理发师,要求理发师就按着这个照片剪。一段时间后,理发师100%完成了任务。事无巨细地将每一处细节完美还原,当然也把没有被照片截进去的部分一刀切了。
造成这个问题的根本原因,就是双方缺少充足的沟通。
在本次开发实践中,我和队友不断地在针对每一处细节进行讨论。队友间的讨论能有效互换看法,从而得到更优解。而更为重要的是,设计人员与开发人员之间的讨论。
前几天我在田同学的博客有如下评论:
记得之前看到一个笑话:
这个世界上难道就没有一种软件和脑机接口,能够把自己所想的自动转化成代码吗?有啊,乙方。
这个笑话很真实,正因真实,我们可以在当中找到一些现实的影子。
真正的工程中或许留给开发人员决定的部分比较多。
或者说是乙方需要跟甲方不断交流,不断探讨需求书中没有提及的内容,以达到互相合作解决问题的目的。那么从这个角度来讲,一个明确的方向和充足的交流是必须的,细节是次要的。
第二周结对编程就非常好的体现了这个特点,不断地出现,问题不断地被解决。
可是换一个角度来想,在现实中真的有这么多正确答案吗?如果没有正确答案,那issue会不会无止尽地多下去呢?我认为现实工程中,正确答案会很少,更多的应该是Open Questions,比如这个按钮放在上面好还是下面好等等。
计网课上,罗老师说过,现在计算机网络所使用的技术更新很快,因为人们还没有找到最好的。正是因为没有最好的,可是又有那么多人要用,需求大,所以要不断找好用的。
软件的开发或许也如此:需求过大——快速开发的demo——不断更新的功能、不断优化的体验。但也有很多产品,经过了长时间的沉淀,出道即巅峰。同样,这里也就涉及到最小价值产品(MVP)还是完美产品(MBP)的问题了。
实践总结
相比于总结,其实我更想说的是,在结对编程之前一定要先了解什么是“结对编程”。《构建之法》用了大篇幅来介绍,他从人员配合、分工、过程的每一步都进行了完整的分析。或许在不看这本书之前,与队友的争执会让我有些心浮气躁,但看了这本书之后,我能清楚地意识到我们只是在对于项目的设计进行争论。同样,他也能认识到这一点。
社会心理学上有一个概念:
“行动—观察者差异”。自己对于某件事的看法,相比别人看见你的行为推测你对于这件事的看法是有差异的。你的行为并不能完全代表你的看法。
这是因为行动者与观察者有着不同的思考、观察角度,所带有的价值就不同。而阅读《构建之法》,相当于在我和我的队友之间建立了相同的价值,我们就能消除这样的“差异”,更加心平气和的去面对“争执”。
对于结对编程的任务建议,我相信课程组会有比我更加深刻而完整的认识。至于我自己的想法,我会在感受部分说到。
CI体验感想
我认为CI的作用非常的强大。CI能够进行Junit单元测试程序的自动化测试,并且计算出相应的代码覆盖率。CI的部署让我们省去了很多额外的测试时间。同时,CI强大的功能支持我们通过url下载的官方包进行测试,每次上传代码之后就能够查看结果。
结对编程感想
3821
lhx同学时间管理能力非常令我佩服,在其他工作的压力之下也能够拿出大量时间和我进行线下的分析讨论与面对面编程。同时lhx同学的分析理解与决断能力在这次结对编程中起到了重要作用,经常将理解上误入歧途的我拉回正道。lhx同学优秀的编码规范也是我们能够完成结对作业的一大助力。以及或许在思考问题的细节方面能够再周全和缜密一点,或许能够更好。当然了,这是一次非常愉快的结对合作,希望都能在软工课上收获满满,取得好成绩。
其实总的来说,结对编程的体验还是很不错的。两个人线下面对面,从需求(指导书)分析到设计,从编码到最后的单元测试,都是及时讨论一起解决的。在分析和设计阶段,能够互相帮助理解需求,集思广益进行架构设计(不过好像我们的架构也挺一般的orz);在编码和单元测试阶段,能够及时纠正编码错误,增添对细节点上的测试等。也很幸运有一个优秀的队友,让这次结对体验更加完美。(如果后续的指导书再斟酌、控制一下,那么此次体验就真的perfect了)。
这次结对作业应该算是有初步的需求不断变动的工程体验了。第二次作业上,既要修第一次的bug,又要增添第一次应该考虑但是课程组未测试的细节,还要更新属于第二次的需求。而且第二次作业需求上的不断更新与细化,为了不大范围的变更代码,我们只好就疯狂打补丁,最后代码效果emmmmm(懂得都懂)。这应该是我们需要进一步学习与改进的部分吧。感谢老师和助教在此部分的准备和及时回复,也希望在后面的阶段会有更多的收获。
3676
在文章的开头我就赞扬了我的队友,我从他的身上学习到了非常多优秀工程师的品质。其中最为突出的一点:测试全面,前面已经提及了。他对于小模块的测试也毫不含糊,在结对编程的过程中,这样的一丝不苟不断地影响着我,让我更加重视测试。而在整个过程中,他更像是一种“驾驶员”的角色。他的代码能力比我更强,而我可能在设计上有些有意义的见解。从头到尾,我们之间的合作都是非常愉快的。
接着实践总结部分的最后,我想来谈一谈结对编程任务。
首先,毋庸置疑的是,这两周的经历让我收获非常多。收获不仅在于代码,设计层面的知识,更是在合作,交流的层面。知识固然重要,但学习别人的优点,与优秀的人交谈,领会他们的思维和思想,更是一件幸福的事。我不仅从我的队友身上学到了很多,我还有机会通过博客的方式,与大佬们进行交流。本人代码能力并不强,身边优秀的同学思考得还比我更加深入,我深感惭愧。当然,这也会不断激励着我变得更好。
其实翻看第二周的博客,我似乎在“反思”。可是当我翻看其他同学的博客时,我能感觉的到,他们才是真正的在反思。而我只是发发牢骚,对大量投入的时间和不对等的回报感到不满。在那篇博客中,我将我们比作“小白鼠”,结对编程比作“实验”,而表达我的“痛苦”。看似“理性”的看待,但实则非常感性。所以我在后面的评论中反思道:
抱歉,这个比喻可能有些不恰当。我并没有觉得课程组在我们身上做实验,课程组对于课程的设置一定是经过深思熟虑的。人非圣贤孰能无过,有一些差错完全可以理解。其实我也在反思自己:自己写博客的时候是否是在发牢骚,而不是真正的思考;自己的能力是不是还没有能够达到课程组的要求,所以才花了这么多时间(相比于其他结对小组,我们的时间也高出了不少)。
但是不管怎么样,我可以看到的是,我们和课程组都在不断地进步!“悟已往之不谏,知来者之可追。”过去的已经过去,而为未来做好充分的准备才是现在最重要的事!
既然结对编程已经结束,或许应该好好反思,写一篇博客,好好睡一觉然后重新出发!