Loading

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

结对编程小结

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

第一部分 结对编程感受

3812:

吸取了第一次结对编程的经验和教训后,这次结对编程,我们交流和协作相当顺利,编程效率明显提高。一个人编码,一个人查看指导书、梳理思路、提示细节,这样的工作方式使我们节省了很多时间,且及时发现了很多隐藏错误。

当然,这次结对编程过程中也存在一些问题,如:指导书的表述不是很明确,存在着很多模棱两可的地方。其中的以下不再赘述说明,常常使我们忘记一些细节异常的处理。本次结对编程最主要的时间花费都在理解指导书和阅读issue上,源于我们没有在编程伊始就对指导书内容进行归纳和分析,这一点我们将在下次编程时改正。

3717:

  • 本次的结对编程地点选在了宿舍,外接大屏真香!
  • 意识到了需求分析的重要性。由于第一次作业需求较少,实现较简单,我们并未将实现中的一些普遍操作进行封装,在本次作业中吃了不少苦头。我们花费了一下午时间来封装底层操作、重写功能实现和开展相关测试。
  • 底层操作动不得!随着项目的逐渐扩大,我逐渐意识到一个很有趣的问题——所有的需求实现都依赖我们封装的几个底层操作,但凡对底层操作有一点点修改,我们的项目就炸了。曾经,我还是动不动就叫喊重构的意气少年;现在,我却感觉,项目大了就构不得了,只能打补丁(狗头。
结对编程

第二部分 项目设计

2.1 架构设计

2.1.1 文件系统

文件系统沿用了先前的基于 Composite 模式的架构设计。

由于本次作业新增了软链接和硬链接,它们都是链接文件,可抽象为条目。并且,硬链接与文件在某些情况下具有相同的对外视图,故设置 FileView 接口进行适配。

类层次如下:

1

本次作业我们抽象出了三个底层操作,用以完成所有需求的实现:

/**
 * @param link 软链接
 * @return 软链接指向的路径对应的文件、目录或硬链接,
 *         如果软链接指向的路径对应的是软链接,需要递归调用
 */
public MyEntry toEntry(SoftLink link);

/**
 * @param entries 路径解析后的各个条目名
 * @param path 路径
 * @return 路径对应的条目的父目录
 */
public MyDirectory getSuperDir(List<String> entries, String path);
    
/**
 * @param path     路径
 * @param redirect 重定向选择
 * @return 路径对应的真实条目,可能是文件、目录或硬链接
 */
public MyEntry getEntry(String path, boolean redirect);
2.1.2 用户系统

本次作业的用户系统需求较小,实现较为简单。(下次再说

2.1.3 系统交互

利用静态方法进行交互。

以文件系统为例:

public static void incrementCmdCount();

public static MyDirectory getRootDir();

public static MyDirectory getCurrentDir();

public static void setCurrentDir(MyDirectory dir);

public static void reset();

2.2 测试

2.2.1 回归测试和覆盖测试

回归测试,对新开发版本的项目进行先前版本的测试,保证没有因为增加新功能而出现新问题。

覆盖测试,本次测试涉及的异常种类较多,异常情况较复杂,没有做到分支和语句的完全覆盖。

5

在本次测试中遇到的问题:

由于文件系统和用户系统无法获取对方的实例,因此我们将文件系统和用户系统的成员变量设置为静态的,在测试时对文件系统和用户系统中的成员变量重置以开展测试。

@Before
public void resetSystem() {
    MyUserSystem.reset();
    MyFileSystem.reset();
}
2.2.2 压力测试

在性能测试方面,我们对文件系统中绝对路径的获取、文件大小的获取和文件的拷贝进行了优化。

在优化前,我们采用缓存的方式存储绝对路径,采用递归的方式获取文件大小和拷贝文件,如果遇到层次较深的目录嵌套,我们的程序就很容易爆栈。

@Test
public void test() {
    MyFileSystem fileSystem = new MyFileSystem();
    try {
        StringBuilder path = new StringBuilder();
        for (int i = 0; i < 2048; i++) {
            path.append("a/");
        }
        for (int i = 0; i < 248; ++i) {
       	    fileSystem.makeDirectoryRecursively(path.toString());
            fileSystem.changeDirectory(path.toString());
        }
        fileSystem.fileWrite("file.txt", "2");
        fileSystem.copy("/a", "/b");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
2

在优化后,我们取消了对于绝对路径的缓存,采用即用即求的方式获取绝对路径;我们将递归替换为层序遍历的方式,来获取文件大小和拷贝文件。

3 4

运行方面,我们没有再遇到爆栈的问题,但获取绝对路径的时间开销却大大提升。鱼和熊掌不可得兼,权衡之下,我们最终选择用时间换空间的方式对代码进行优化。

第三部分 PSP表格记录

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