Loading

软件工程--结对编程小结

项目 内容
教学班级 2021年春季软件工程(罗杰 任健)
作业要求 完成一个简单的文件管理系统
GitLab项目地址 GitLab
结对同学学号后四位 3812 3717

第一部分 结对编程感受

结对编程的过程是先苦后甜的,起初,由于缺乏沟通以及编程习惯各异,我们在两小时内仅完成了一个解析字符串的工具类的编写,效率堪忧。随后,我们进行了一次约半小时的交流,确定了各个需求的大体实现逻辑,效率大大提升。

同时,体验完这一次的结对编程,我们也对结对编程有了更深的理解。结对编程就像是驾驶员与导航员的关系,驾驶员所注意不到的细节,需要导航员及时补充;驾驶员长时间驾驶疲劳后,也可以与导航员互换角色,得到一定的休息,同时也从更客观的角度来审视代码。

结对编程确实有相较于单人编程的优势,但是也存在着一些刚开始结对编程让人不适应的地方,需要双方的磨合。

结对编程的优势:

  1. 在分析问题时能够看得更全面,更多解决思路。在一开始的设计讨论的时候,关于查找目录,我的想法是进入类中进行递归查找,最后返回目录,但是这个不论是在异常的处理上,还是在复杂度上都有着诸多的不合理之处,之后我们讨论决定在顶层利用循环寻找目录,可以方便处理异常的输出,也能让代码解释性更强;同时在阅读指导书的时候,也能够双方相互讨论一起理解指导书中的意图,也能够相互提醒细节,避免遗漏;
  2. 在编程时能够减少细节问题。一个是驾驶员,一个是导航员,驾驶员在编写代码时,可能会疏忽一些细节,比如异常,比如数组越界,比如未按照指导书要求撰写;
  3. 代码规范。因为是结对编程,代码需要对双方都有着较高的可读性,不能仅仅我能读懂就行,所以在命名,在函数构造时,就会主动去将其完善成可读性高的结构和名称;
  4. 相互学习和进步。在结对编程时,能够看到和学习到对方的优点,比如模块的使用,模块的安排,函数的抽离,有些自己不知道能够进行优化的地方,也能在结对编程时从对方身上学到。

结对编程需要让人磨合和适应的部分:

  1. 命名。这个可以说是我们这次最纠结的地方了,我常常习惯关于中间变量就命名随意,而他对于每个命名都有着“强迫症”,希望每个变量的行为都能与其命名相符合;
  2. 接受领航员的身份。在开发的时候,一个人进行编码,一个人只能在旁边看着,着实有点不适应,感觉效率偏低,但是从结果来看,整体的效率比想象的要高,在编写过程中,因为两个人同时关注,在bug方面的没有多少产出。

在我们的结对过程中,典型的场景是:编码者实现具体需求,审查者思考实现逻辑并设计边界数据;在编码者完成方法编写时,审查者呈上精心设计的数据开展单元测试。测试的成功往往给我们带来信心的倍增。

1881616637019_.pic_hd

第二部分 项目设计思路

2.1 项目要求

本次作业需要实现一个基于内存的文件系统,它允许用户通过各类输入指令来进行文件的增删查改等交互。

2.2 架构设计

本次作业基于 Composite 模式进行架构设计。目录与文件虽是不同类型的对象,却有许多共同属性(如:命名、大小、绝对路径、创建时间、修改时间等),且都可以被放至某一目录中,故将目录与文件统一视为“条目”进行类层次设计。

下图展示了本次作业的类层次:

1881616637019_.pic_hd

MyFileSystem 作为上述类层次的使用者,解析输入指令中的绝对路径或相对路径,寻找对应的条目对象,执行相关的操作并输出信息。

2.3 单元测试

2.3.1 测试设计思路

在设计测试的时候,我们主要从三个方面考量测试内容,分别是模块测试,异常测试和功能测试:

  1. 模块测试

在我们的设计中,我们将字符串处理提取了出来,并针对文件和文件夹进行了分别处理;同时针对特定的文件系统操作进行了专门的测试,如创建文件夹,创建文件,文件内容测试等。

截屏2021-03-24下午11.07.29
  1. 异常测试

在设计上,我们总结出了四类异常,分别是DirCannotRemoveExceptionPathExistExceptionPathNotExistExceptionPathFormatWrongException,并在测试时要求抛出指定的异常才算完成正确性测试。

		@Test
    public void testMkdirTwo() {
        String dirPath = "/";
        try {
            MyFileSystem fileSystem = new MyFileSystem();
            fileSystem.makeDirectory(dirPath);
            fail("expected exception does not occur");
        } catch (PathExistException e) {
            assertEquals(e.getMessage(), "Path " + dirPath + " is invalid");
        } catch (Exception e) {
            e.printStackTrace();
            fail("unexpected exception");
        }
    }
  1. 功能测试

在完成模块测试和异常测试之后,我们需要结合不同模块的动作进行综合测试,检查不同动作之间的交互性和文件系统整体的功能。

    @Test
    public void testOne() {
        try {
            MyFileSystem fileSystem = new MyFileSystem();
            assertEquals(fileSystem.list("/"), "");
            assertEquals(fileSystem.makeDirectoryRecursively("/home/test"), "/home/test");
            assertEquals(fileSystem.makeDirectory("home/a"), "/home/a");
            assertEquals(fileSystem.makeDirectory("home/b"), "/home/b");
            fileSystem.touchFile("home/c.txt");
            fileSystem.touchFile("home/f.jpg");
            fileSystem.touchFile("home/gg.jpg");
            assertEquals(fileSystem.list("home"), "a b c.txt f.jpg gg.jpg test");
        } catch (Exception e) {
            e.printStackTrace();
            fail("unexpected exception");
        }
    }
2.3.2 测试覆盖性

在测试的覆盖性上,我们达到了98%的语句覆盖率,,对所有语句和所有涉及到的异常情况进行了测试,都表现符合预期。

截屏2021-03-24下午11.18.25

第三部分 PSP表格记录

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 15 15
· Estimate · 估计这个任务需要多少时间 15 15
Development 开发 410 610
· Analysis · 需求分析 (包括学习新技术) 45 45
· Design Spec · 生成设计文档 15 15
· Design Review · 设计复审 (和同事审核设计文档) 10 10
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 20
· Design · 具体设计 30 40
· Coding · 具体编码 180 240
· Code Review · 代码复审 60 120
· Test · 测试(自我测试,修改代码,提交修改) 60 120
Reporting 报告 50 60
· Test Report · 测试报告 30 30
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 10 20
合计 475 685
posted @ 2021-03-25 12:51  DanGuge  阅读(143)  评论(4编辑  收藏  举报