结对编程第一阶段小结
结对项目第一阶段小结
基本信息
项目 | 内容 |
---|---|
本作业所属课程 | 2020春季软件工程(罗杰 任健) |
本作业要求 | 采用结对编程的形式完成一个简单的文件管理系统 |
- 学号后四位:1045、3298
- Gitlab:https://gitlab.buaaoo.top/2021_alige_homeworks/pair_works/2021_xinyu_deng-shuai_luan_pair_work
结对编程感受
1045
之前做过很多合作项目,但从来没有进行过结对编程。第一次进行结对编程之前,内心还是比较怀疑结对编程的效果的,毕竟本来两个人可以同时进行的工作现在要两个人同时做。但是进行尝试之后就发现了一些好处。
在进行具体编码的时候,我大部分时间是负责“领航员”的任务,在不用进行具体编写的情况下,我就不用过分在意编程的细节,这让我能够看清楚整体架构的可能存在的问题,也给我足够的精力去关注可能存在的细节问题,不少问题都在它实际发生之前就被我们注意到了。此外,我们这次进行了很详细的单元测试,单元测试的代码量几乎将近三倍于主程序,但是却没有发现任何的功能实现上的缺陷,发现的错误都是和需求文档(指导书)有出入造成的。可见,结对编程确实大大提高了代码的质量,我认为代码质量的提高,在大型项目中,造成的效率提升确实大于多人同时工作带来的产量提高。
但是结对编程也确实有一些困难。
首先就是交流,这次结对编程作业,队友对我很信任,我有一些能够提高代码质量的想法却解释不清楚的时候,比如通过迭代器提供视图来进行访问、通过统一接口暴露修改对象状态的方法等,能够让我先实现出来然后他在照着我的实现来复查,但倘若两人有不同的想法的时候,可能就会僵在这里争执一阵子。虽说这样的争执确实是有意义的,能够写出最好的实现,但是对效率的损失太大了,而且这相当于某种程度的提前优化,在全局看来,这种优化很可能是无关痛痒的,但却占用了大量的时间。
另一个困难就是同步,在以往的分工编程项目时,大家只需要规定好一些检查时间,过上几天大家汇总一下,这是异步的;但是结对编程,要求两个人在同一时间、同一地点写着同一份代码,这是同步的,是需要一定代价完成的同步。对企业中,可能尚且结对双方有较为统一的作息,但是对于学生来说,上的课不相同,就不容易找到重合的时间。我们这次因为我这学期课少,才能够兼顾队友的空闲时间,听说不少其他小组时间都十分紧迫。另一个同步带来的困难就是地点的选择,结对编程需要频繁交流,图书馆、空教室就不合适,我和队友也不是同一个公寓楼,疫情下不允许串宿舍,所以我们只能在食堂进行,而食堂又没有插座,电脑的性能下降导致IDE有些卡顿,续航问题也导致结对编程难以长时间进行。
总的来说,结对编程确实有一定意义,但却需要一定的前提,需要结对双方有比较的交流,能够熟悉对方的描述方式,需要有相对统一的时间安排、需要有比较合适的空间,但是结对编程也能确确实实提高代码的质量,能够在实现的时候规避一些坑点,写出缺陷比较少的代码。相比而言,我认为结对编程更像是一种“锦上添花”的方法,花费了更多的技术外的资源,突破了技术能力的限制,完成质量更高的开发工作。
3298
起初感觉这个作业应该不会很难,但是写着写着就感觉不太对劲,问题越来越多,看指导书不仔细导致花费了很多时间,渐渐的就感受到了被oo支配的恐惧。写代码共耗费了四个小时,测试花费了四个多小时,再加上其他的一些讨论的时间,花费的时间可能有十几个小时了。我平时课比较多,周末还要上两个半天的课,能够找到凑到一块的时间不多。而且讨论区的回复很慢,一旦遇到问题,可能会耽误很长时间才能等到回复。为了不耽误进度我们就只能选择跳过,但是回头再看一些东西的时候总感觉已经乱掉了,第二天可能还要继续改。
好在跟我结对的小伙伴思路清晰,全程带飞。跟我结对的小伙伴很强,代码风格,架构设计,单元测试能力以及编码能力都远在我之上,我写着写着可能就已经思绪紊乱了,但是大哥依旧不慌不忙,指导我这个地方应该怎么些,这个地方应该怎么设计,让我逐渐留下了oo不思进取的眼泪。两个人坐一起写代码其实需要很高的配合的,跟我结对的同学能够全程参与进来,指导我写代码,同时一起探讨,而我自己思考的时间就少了一些,在他重构项目得时候,我却帮不上什么忙,只能去配置ci,搞搞加密。在他做单元测试的时候我也完全帮不上什么忙,我当年oo的时候全靠对拍,就不太会做单元测试。他也给了我一些设计上的启发,例如modify可以使用链式编程的方法返回一个对象,使用内部类在内部规定modify会修改的方法等。
对于这次作业花费的时间还是蛮多的,尤其是看到舍友的班不需要写这些东西的时候,而我却在做oo第五次作业,而且这个作业一周一次博客,就有点感觉不值,两学分的课却要一周投入两天的时间。我也不是很支持结对编程搞成评测机的模式,感觉自己像是提前来帮学弟体验oo的,免费帮课程组做实验,想到当年为学弟提议魔鬼电梯的时候,我以为一切都结束了,看来还是年轻。而且评测模式指导书都给你写好了,几乎没有了做需求分析的必要,体感就是完全在给别人写代码,而不是给自己,又带上了打工人的痛苦面具。
程序设计和实现思路
本次作业操作的实体主要为目录
和文件
两类,这两类实体有一些共通之处:
- 通过
info
查询,输出相同的格式; - 可以放到一个
目录
下,具有相对唯一的名字; - 需要跟踪创建时间和修改时间;
- 需要求大小;
所以可以将共通之处抽象出来,由于名称、修改时间、创建时间描述的是状态,需要通过字段来描述,故而共通之处适合作为一个基类而不是一个接口。而求大小二者有不同的规则,故而适宜作为一个抽象方法。因此,我们设计了共同的抽象基类FileControlBlock
,其有两个子类File
和Dir
分别用于描述文件和目录。
对于文件和目录,既有查询操作,也有修改操作,修改操作除了修改本身,还需要更新修改时间。故而,我们将查询操作和修改操作进行了分离,查询操作可以直接利用对象进行查询。而修改对象需要通过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 |