结对编程第一阶段小结

结对项目第一阶段小结

基本信息

项目 内容
本作业所属课程 2020春季软件工程(罗杰 任健)
本作业要求 采用结对编程的形式完成一个简单的文件管理系统

结对编程感受

1045

之前做过很多合作项目,但从来没有进行过结对编程。第一次进行结对编程之前,内心还是比较怀疑结对编程的效果的,毕竟本来两个人可以同时进行的工作现在要两个人同时做。但是进行尝试之后就发现了一些好处。

在进行具体编码的时候,我大部分时间是负责“领航员”的任务,在不用进行具体编写的情况下,我就不用过分在意编程的细节,这让我能够看清楚整体架构的可能存在的问题,也给我足够的精力去关注可能存在的细节问题,不少问题都在它实际发生之前就被我们注意到了。此外,我们这次进行了很详细的单元测试,单元测试的代码量几乎将近三倍于主程序,但是却没有发现任何的功能实现上的缺陷,发现的错误都是和需求文档(指导书)有出入造成的。可见,结对编程确实大大提高了代码的质量,我认为代码质量的提高,在大型项目中,造成的效率提升确实大于多人同时工作带来的产量提高。

但是结对编程也确实有一些困难。

首先就是交流,这次结对编程作业,队友对我很信任,我有一些能够提高代码质量的想法却解释不清楚的时候,比如通过迭代器提供视图来进行访问、通过统一接口暴露修改对象状态的方法等,能够让我先实现出来然后他在照着我的实现来复查,但倘若两人有不同的想法的时候,可能就会僵在这里争执一阵子。虽说这样的争执确实是有意义的,能够写出最好的实现,但是对效率的损失太大了,而且这相当于某种程度的提前优化,在全局看来,这种优化很可能是无关痛痒的,但却占用了大量的时间。

另一个困难就是同步,在以往的分工编程项目时,大家只需要规定好一些检查时间,过上几天大家汇总一下,这是异步的;但是结对编程,要求两个人在同一时间、同一地点写着同一份代码,这是同步的,是需要一定代价完成的同步。对企业中,可能尚且结对双方有较为统一的作息,但是对于学生来说,上的课不相同,就不容易找到重合的时间。我们这次因为我这学期课少,才能够兼顾队友的空闲时间,听说不少其他小组时间都十分紧迫。另一个同步带来的困难就是地点的选择,结对编程需要频繁交流,图书馆、空教室就不合适,我和队友也不是同一个公寓楼,疫情下不允许串宿舍,所以我们只能在食堂进行,而食堂又没有插座,电脑的性能下降导致IDE有些卡顿,续航问题也导致结对编程难以长时间进行。

总的来说,结对编程确实有一定意义,但却需要一定的前提,需要结对双方有比较的交流,能够熟悉对方的描述方式,需要有相对统一的时间安排、需要有比较合适的空间,但是结对编程也能确确实实提高代码的质量,能够在实现的时候规避一些坑点,写出缺陷比较少的代码。相比而言,我认为结对编程更像是一种“锦上添花”的方法,花费了更多的技术外的资源,突破了技术能力的限制,完成质量更高的开发工作。

3298

起初感觉这个作业应该不会很难,但是写着写着就感觉不太对劲,问题越来越多,看指导书不仔细导致花费了很多时间,渐渐的就感受到了被oo支配的恐惧。写代码共耗费了四个小时,测试花费了四个多小时,再加上其他的一些讨论的时间,花费的时间可能有十几个小时了。我平时课比较多,周末还要上两个半天的课,能够找到凑到一块的时间不多。而且讨论区的回复很慢,一旦遇到问题,可能会耽误很长时间才能等到回复。为了不耽误进度我们就只能选择跳过,但是回头再看一些东西的时候总感觉已经乱掉了,第二天可能还要继续改。

好在跟我结对的小伙伴思路清晰,全程带飞。跟我结对的小伙伴很强,代码风格,架构设计,单元测试能力以及编码能力都远在我之上,我写着写着可能就已经思绪紊乱了,但是大哥依旧不慌不忙,指导我这个地方应该怎么些,这个地方应该怎么设计,让我逐渐留下了oo不思进取的眼泪。两个人坐一起写代码其实需要很高的配合的,跟我结对的同学能够全程参与进来,指导我写代码,同时一起探讨,而我自己思考的时间就少了一些,在他重构项目得时候,我却帮不上什么忙,只能去配置ci,搞搞加密。在他做单元测试的时候我也完全帮不上什么忙,我当年oo的时候全靠对拍,就不太会做单元测试。他也给了我一些设计上的启发,例如modify可以使用链式编程的方法返回一个对象,使用内部类在内部规定modify会修改的方法等。

对于这次作业花费的时间还是蛮多的,尤其是看到舍友的班不需要写这些东西的时候,而我却在做oo第五次作业,而且这个作业一周一次博客,就有点感觉不值,两学分的课却要一周投入两天的时间。我也不是很支持结对编程搞成评测机的模式,感觉自己像是提前来帮学弟体验oo的,免费帮课程组做实验,想到当年为学弟提议魔鬼电梯的时候,我以为一切都结束了,看来还是年轻。而且评测模式指导书都给你写好了,几乎没有了做需求分析的必要,体感就是完全在给别人写代码,而不是给自己,又带上了打工人的痛苦面具。

程序设计和实现思路

本次作业操作的实体主要为目录文件两类,这两类实体有一些共通之处:

  1. 通过info查询,输出相同的格式;
  2. 可以放到一个目录下,具有相对唯一的名字;
  3. 需要跟踪创建时间和修改时间;
  4. 需要求大小;

所以可以将共通之处抽象出来,由于名称、修改时间、创建时间描述的是状态,需要通过字段来描述,故而共通之处适合作为一个基类而不是一个接口。而求大小二者有不同的规则,故而适宜作为一个抽象方法。因此,我们设计了共同的抽象基类FileControlBlock,其有两个子类FileDir分别用于描述文件和目录。

对于文件和目录,既有查询操作,也有修改操作,修改操作除了修改本身,还需要更新修改时间。故而,我们将查询操作和修改操作进行了分离,查询操作可以直接利用对象进行查询。而修改对象需要通过modify(int currentTime)方法获得一个ModifyHandler,通过这个handler来进行修改。这样的目的在于进行修改前必定调用了modify方法,得以更新修改时间,另一方面将查询方法和修改方法进行了分离,结构更加清晰。使用方式如下:

workDir.modify(currentTime).makeDir("sub");

除了这两个实体的设计外,本系统经常使用且比较繁琐的是通过字符串路径来寻找到对应的Dir工作路径,我们将其抽象成一个类PathController,专门管理根目录、当前目录、路径解析。

主要类的UML图如下:

时间花费记录

PSP2.1 Personal Software Process Stage 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
- Estimate - 估计这个任务需要多少时间 180 600
Development 开发
- Analyze - 需求分析(包括学习新技术) 10 10
- Design Spec - 生成设计文档 10 10
- Design Review - 设计复审(和同时审核设计文档) 10 10
- Coding Standard - 代码规范 (为目前的开发指定合适的规范) 10 10
- Design - 具体设计 10 10
- Coding - 具体编码 120 220
- Test - 测试(自我测试,修改代码,提交修改) 120 240
Reporting 报告
- Test Report - 测试报告 10 10
- Size Measurement - 计算工作量 10 10
- Postmortem & Process Improvement - 事后总结,并提出过程改进计划 60 120
合计 380 680
posted @ 2021-03-23 21:02  SnowPhoenix  阅读(130)  评论(2编辑  收藏  举报