结对编程#2
结对项目博客
项目 | 内容 |
---|---|
课程 | 2021春季软件工程(罗杰 任健) |
GitLab项目地址 | 项目地址 |
队员1学号 | 3567 |
队员2学号 | 3018 |
结对编程感受
队员1
第二次结对编程作业的难度相比之前加大了许多,我和我的队友进行了分工,我负责用户相关的代码编写,队友负责文件与目录相关代码的编写,相对来说这次作业这两个部分的独立性还是很大的,同时有了第一次作业的磨合,大家也都在适应对方的编码习惯,所以在两部分代码的协调方面比第一次作业顺利很多。同时,两个人在阅读指导书、debug的过程中互相提醒,可以有效消除认知惯性。
队员2
本次作业是第二次进行结对编程,客观上而言这次作业的难度有很大的提升,在阅读指导书的过程中也遇到很多的困难和问题,虽然指导书十分详实,但是在编码过程中很容易忽视细节,比如对异常的抛出以及及时return防止一个指令多次执行。这次结对编程主要是在线上开展,在遇到问题时及时交流反馈,对两次作业的迭代中产生的区别进行分析,且对代码有较大的重构。在结对编程的过程中,我们负责不同部分的编码,进行了共同测试,发现了许多问题。通过不断复审,在初步编码后,在一个庞大的架构下逐步完善细节,第二次结对编程最大的感受就是需要修复的问题增加了许多,修复bug的过程非常艰难,花费的时间也很长。
现场结对编程
腾讯会议
设计和实现思路
在本地结对编程中,增加或修改了以下几个类:
MyUserSystem:实现了UserSystem接口。
User:用户类。
Group:小组类。
MyFileSystemException:继承了FileSystemException,用于抛出invalid异常。
MyFileSystemExistException:继承了FileSystemException,用于抛出exists异常。
MyUserSystemException:继承了UserSystemException,用于抛出invalid异常。
Dir
将问题中的目录抽象为Dir。
- 增加了目录类中的Map属性,用于存储软链接、硬链接文件,同时在Dir内存储了Dir所属的User、Group。
- 在目录下的文件操作中,增加了针对链接文件的分支。
- 实现了在目录下创建链接文件的方法。
- 实现了产生本身副本的克隆方法,用于copy指令。
- 仍然使用缓存的方式保存大小与绝对路径,降低查找时间。
File
将问题中的文件抽象为File。
- 增加了srcFile、srcDir、linkFlag等属性,用于区分文件为普通文件、软链接文件还是硬链接文件。
- 在File中存储了链接文件指向的File类,根据linkFlag的不同决定调用属性时选择指向的文件的属性或者是自身的属性。
- 链接文件有两个需要区分的路径:自身的绝对路径和指向对象的绝对路径。
- 在各个获取File类属性的方法中增加了针对链接文件的分支。
- 在File类内也增加了findFile、findDir方法,用于对链接文件的查找。
User
- 将用户抽象为User
- User主要维护了用户所在的主用户组(Group)和用户所在的用户组(Hashmap)
- 关注删除用户时,主组是否应该删除,以及用户所在的所有组都应该将该用户从组内删除
Group
-
将问题中的用户组组抽象为Group。
-
Group需要维护该组的主用户以及该组的所有用户
-
应关注删除组时将该组从该组的所有用户维护的组中删除
MyFileSystem
实现了FileSystem接口。
- 将nowDir、headDir、orderNum设为了静态变量,方便User、Group类的调用。
- 修改了目录查询finDir以及路径倒数第二层目录查询findDirThatHasDirOrFile的方法,使得在路径中存在链接时能够正确地替换绝对路径,从而寻找到查询目标。
- 修改了mkdir -p的方法,使得指令具有原子性,避免了一边创建目录一边抛出异常的情况。
- 本次迭代对于之前的指令并不需要在文件系统类中进行很多修改,例如,增加了info需要展示的内容,具体实现在Dir、File内部增加针对不同类型的分支即可,而在外侧只需布置一个接口。
- 增加了软链接、硬链接方法,设计思路为根据路径寻找到目标src以及dst,再根据目标是否为链接文件、普通文件、目录进行分支,从而覆盖所有情况,在异常抛出时根据异常的不同,分成路径invalid异常和路径exists异常。
- move和copy方法与链接方法类似逻辑,具体细节比较复杂,针对链接文件的mv和cp会产生多种情况,需要一一区分。
MyUserSystem
实现了UserSystem接口。
- 将nowUser、returnDir设为了静态变量,用于与MyFileSystem的交互。
- 抛出异常的顺序大致为:指令权限相关异常>命名相关异常>每条指令下说明的异常
不足
完成此次作业之后,我们进行了讨论与思考,发现代码存在以下的不足,导致代码编写困难,遇到的问题多。
- MyFileSystem和MyUserSystem之间的交互选择用静态变量,这样的做法不是很好的选择,我们在进行单元测试的编写时也因为这个问题遇到了很多麻烦,但是因为时间紧张没有进行改进,在下次迭代中会创建一个Manager类,通过这个类完成类与类之间的交互。
- 对于软硬链接文件的处理,应该将软链接文件和硬链接文件分别抽象成两个类,重写File中的一些方法。
UML
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
Estimate | 估计这个任务需要多长时间 | 10 | 10 |
Development | 开发 | ||
Analysis | 需求分析(包括学习新技术) | 50 | 80 |
Design Spec | 生成设计文档 | 30 | 25 |
Design Review | 设计复审(和同事审核设计文档) | 20 | 20 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 10 | 10 |
Design | 具体设计 | 90 | 120 |
Coding | 具体编码 | 600 | 840 |
Code Review | 代码复审 | 300 | 540 |
Test | 测试(自我测试,修改代码,提交修改) | 480 | 600 |
Reporting | 报告 | ||
Test Report | 测试报告 | 30 | 30 |
Size Measurement | 计算工作量 | 15 | 15 |
Postmortem&Process Improvement Plan | 事后总结,并提出过程改进计划 | 20 | 30 |
合计 | 1655 | 2320 |
这次作业花费的时间比第一次结对作业要多不少,原因在于此次作业的架构变得更加复杂,需要处理的细节部分也增加了很多。在工作量增加不少的情况下,需要更全面的测试,因此我们在复审以及测试过程中花费了很多时间。