阿拉伯人说的纳斯纳斯,亦即索马里人说的匈古夫——结对编程1
标题含义:纳斯纳斯是阿拉伯传说里的半边人,匈古夫同理。标题暗示结对编程中两个人都发挥对等的作用且不可或缺,并且对一个事物的两种说法暗示了结对编程中两人需要通过沟通来确认彼此对同一个事物的看法。
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 2021春季软件工程(罗杰 任健) |
这个作业的要求在哪里 | 作业要求 |
GitLab项目地址 | 2021_Ziming_Yang-Jingwen_Tian_pair_work |
学号后四位 | 3080 3420 |
我在这个课程的目标是 | 积累软件开发经验,提高工程能力 |
这个作业在哪个具体方面帮助我实现目标 | 体验结对编程,培养集体意识,提高开发能力 |
一、结对编程感受
本次结对编程使用腾讯会议工具,进行语音交流与屏幕共享,完成项目设计、编码、测试以及复审过程。在开始时,尝试使用了 IDEA 的 code with me 插件,发现由于网络原因,导致以 YANG 作为 User1,TIAN 作为 User2 时虽然可以使用插件功能,但同步效果较差,二者角色对调时,由于配置因素,无法正常使用该插件,遂放弃。
FROM TIAN
在结对编程的过程中,通过观察对方的设计思路、编码方法,与自己的想法进行对比,能够体会到自己的不足,学习到对方好的编码习惯、架构特点,也能够及时从不同角度指出对方设计中可能存在的问题,使设计架构更完整、代码质量更高。同时,这种直接观看对方设计、编码,与对方直接交流问题的过程,能够更加清晰地体会到一些老师课上所讲的问题,比如减少耦合性、各部分设计独立完整等,达到一种互促学习的效果。虽然两个人一起进度有点慢,因为彼此思路不相通,经常需要互相讲解,但是这个过程也可以提高代码质量,很大程度上减少了debug的时间。
FROM YANG
本次的结对编程是一次很有趣的实践。虽然我们选择了以腾讯会议的形式进行,没有做到完全的同一台电脑前编程,但是实践过程中仍然保持了“驾驶员”和“领航员”身份的及时切换。在设计前,我们首先对彼此的编码习惯进行了沟通,最后选定了以OO时的编码规范为基础,对部分严格要求进行可容忍的放松,使得之后的编程过程中没有出现因编码习惯不和而进行大幅修改的情况。在设计和编程过程中,我们贯彻了交流至上的理念,在发现问题或者有想不明白的地方时,及时发问、讨论交流。对于“领航员”来说,这不仅发现了代码的问题,也是对自己的一种检定:自己编程时是否也会出现类似问题;而对于“驾驶员”来说,讲述自己编码时的思路可以视为小黄鸭debug法的更高阶实践,是对自己编码的全面梳理。而且在最后的单元测试编写过程中,双方可以同时编写单元测试,提高了效率。
但是诚如“过早的优化是万恶之源”所言,结对编程作为敏捷开发的一种实践模式,追求对代码不间断的复审。然而由于我们本身所具有的局限性,对于提出的问题,往往只能给出一个补丁式的修改,使得某些方法在最后已经陷入了不得不重构而重构又涉及者众的两难境地。
所以结对编程好吗?好,这种方式确实能让我们提高代码质量,并且互相学习。
那么结对编程是万灵药吗?不尽然。如果以从结对编程中学习为目的,它显然利大于弊,能有一个人随时从另一视角切入显然是一种有益的补充。而如果以更好的工程质量为目的,它的利弊就需要权衡,如果两人的架构能力都比较有限,在“领航员”提出问题时,“驾驶员”就容易一叶障目,仅仅局限于自己刚写的几行代码进行修改,而忽略了bug背后的设计问题。这部分问题的解决有赖于更深入的思考,在结对编程这种及时性强的环境中不容易做到。
二、设计实现思路
本次文件管理系统的实现中,我们设计了一个FileSysEntry
类来作为目录类和文件类的父类,使得二者能够更好地统一在一个数据结构中,实现一些统一的属性(name、abspath、create_time、modify_time、size)
和get、set、info
方法等。
基于文件和目录都具有的info
操作,我们设计了一个Infoable
接口,具有info
方法,返回要求中的info
信息,同时使FileSysEntry
实现这个接口。(本意是使用基于接口的编程方法,但是在编码完成后,由于继承的实现,发现info
方法并不具有独立设置接口的特殊性,故最终取消了Infoable
接口)
对于整个文件系统,我们设定它具有根目录和当前目录属性。
对于文件结构的存储,我们选择在目录类中设置Treemap
属性,以文件/目录名为键值,使它能够按名称字典序有序地存储子目录或文件(方便list
操作),在查找文件时,可根据路径逐层向下查找获取文件对象。
对于路径的解析相关操作,我们设计了一个Parser
类,实现解析路径、上层目录、文件名,判断是否为绝对路径,拼接路径等静态功能性方法。
为了设计架构的清晰性、便于调试,我们将过程中可能出现的异常做了区分,并均继承课程组给出的异常抽象FileSystemException
类。
最终架构如下
三、PSP表格记录
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 20 |
Development | 开发 | 770 | 1070 |
· Analysis | · 需求分析 (包括学习新技术) | 40 | 20 |
· Design Spec | · 生成设计文档 | 40 | 40 |
· Design Review | · 设计复审 (和同事审核设计文档) | 50 | 40 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 360 | 600 |
· Code Review | · 代码复审 | 60 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 150 | 240 |
Reporting | 报告 | 105 | 90 |
· Test Report | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 30 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 45 | 40 |
合计 | 905 | 1180 |