2021S软件工程——结对项目第一阶段

2021春季软件工程(罗杰 任健)

项目地址

1020 1169


1 结对感受

结对照片

总体来说,结对编程与之前的个人编程感觉有很大的不同。有如下几个方面:

  1. 在写代码的时候要慎之又慎,因为不仅要自己审核,也要面对同伴的审核,这是很重要的点。
  2. 如何配合也是一个很重要的点。怎样把时间有效的利用起来,而不是在消磨在内耗、扯皮上。
  3. 如果不能面对面编程,怎样利用好腾讯会议。
  4. 不同于单人编程,怎样在结对编程中复审。

从我们结对的情况来看,因为是第一次结对编程,遇到了很多未曾设想的困难,我就想当然的认为:结对编程嘛,就是他带电脑,我拿键盘,他写累了我写,我写累了他写的编程,有什么的呢?

  • 不思考整体框架,直接上手:

    但是上手之后就不一样了,往往伙伴敲了几行,我就会问他:你创建这个变量什么目的?这个问题你打算怎么解决?我们该怎样设计类?该设计怎样的接口呢?你这个方法是打算怎么设计呢?调用几个变量呢?用什么容器呢?......全是这样细枝末节的事情,导致的就是双人编程效率奇低,因为没有写几行就被打断了。

    而且,两个人的话,不怎么适合深入思考,想的都是——我怎么赶快给伙伴一个答复,然后就删了改、改了删。我认为,这是因为我们没有提前写好设计文档,直接上手编程,想着脚踩西瓜皮,滑到哪里算哪里。这在这样的小工程、小项目还比较好说,但是到了大工程、大项目的情况下,就有可能遇到推倒重来的问题。应当对于整个软件的大体结构、框架有初步的认识,再开始编程。

  • 不写注释,可读性差:

    此外,双人的结对编程,比起单人编程,更加强调代码的可读性。当我们编写代码的单元测试的时候,发现很多方法仅仅靠一个方法名来望文生义,是不够的了解这个方法是做什么的。导致进行单元测试的时候,我需要重读方法,需要了解这个的大体流程,然后才能编写测试样例。最终测试本身花费了不少时间。

    主要原因,是没有写注释的习惯。可能我们的编程还停留在——“功能完成就行”的程度,毕竟之前都是那样写的,写注释也不加分hhhhh,时间还那么紧,哪有时间写注释?但是仔细想想,其实重读代码的时间,不见得就比写注释少很多。而且写注释这件事情,实在是功在当代,利在千秋。注释应当包含:创作者、联系方式、变量用途、方法目的、输入格式、大体实现方法之类的增加程序可读性成分的东西。养成写好注释的方法是我们需要总结的事情。

  • 任务分配不明确:

    这主要体现在两个人的编程水平不同,对于项目涉及的领域所了解的深度不同。导致一个伙伴“能者多劳”,另一个伙伴“紧抱大腿”(说的就是我)。目前来看,因为作业给的时间本身就比较紧张,小组也想赶快把作业完成,而且交给弱鸡去写可能又慢、bug还多,会耽误太多的时间,然后就出现了上面的问题。(ps:某个弱鸡找到了bug还不会改,改了还引入新bug,还是大佬亲自下手操刀解决的问题。)我觉得可能不止我们小组存在这样的问题(也可能确实我们小组的弱鸡太菜了),那么任务应当怎样的分配呢。

    我想作为被动的一方,应当主动阅读代码,主动理解代码的功能,主动去写设计文档和单元测试,总结的时候也要仔细考虑后续的迭代,主动了解集成测试、主动了解怎么写单元测试。否则总是做这种紧抱大腿的事情不好hhhhh。

总体而言,目前来看,遇到的很大的问题就是以上所列举的。结对编程,或者是未来的团队编程,怎么做好交流是一个很重要的课题:怎样能够有效交流?怎样能够不浪费时间?

这些问题是我们之后的编程过程中会不断遇到、不断磨合的。而遇到这些问题总结的经验,可能在我们之后的生产实践中会用得上。

2 设计与实现思路

设计思路:

  1. 将文件与目录的共性特征抽象出来,建立一个父类
  2. 整个文件系统为树形结构,根节点即为根目录,每个目录/文件为一个节点,每个节点记录自己的父节点
  3. 文件为叶节点、目录可以有子节点
  4. 创建、删除操作即对文件系统树增加、删除节点
  5. 对文件有特殊的写入操作
  6. 文件系统类中记录当前所在节点,cd操作时更新该记录

实现思路:

​ 根据以上的设计思路,抽象出了四个类:MyFileSystem File Directory FileOrDirectory,其中,FileOrDirectoryFile Directory的父类。

MyFileSystem继承官方包的FileSystem类,实现相关方法

FileOrDirectory的设计如下:

成员变量:

private final String name;
private BigInteger size;
private final int createTime;
private int modifyTime;
private Directory prev;

方法:

public int getModifyTime();
public void setModifyTime(int modifyTime);  //在文件或目录发生变化时调用
public void setSize(BigInteger size); //在文件或目录大小发生变化时调用
public BigInteger getSize();
public String getName();
public Directory getPrev();
public void setPrev(Directory prev); //为根目录特殊设计
public String getAbsolutePath(); //获取当前文件或目录的绝对路径
public String getInfo(); //获取Info

File类增加成员变量content,并有写入/修改content的方法,并且修改时更新直到根目录的所有目录大小,较简单。

Directory类设计如下:

成员变量:

private final HashMap<String, Directory> subDirs;
private final HashMap<String, File> files;

​ 使用HashMap存储子目录和子文件,实现使用文件或目录名字作为key,需要查询复杂度较低。

方法:

public void addDir(Directory subDir, int modifyTime);
public void addFile(File file,int modifyTime);
public Directory getSubDir(String name);
public File getFile(String name);
public boolean nameDuplicated(String name); //判断是否重名
public String getList(); //获取所有子目录和子文件
public void deleteFile(String name, int modifyTime); //删除文件时更新直到根目录的目录大小
public void deleteDir(String name, int modifyTime); //删除目录时更新直到根目录的目录大小

整体的uml图如下:

3 时间记录

PSP2.1 预估耗时(分钟) 实际耗时(分钟)
Planning 20 10
·Estimate 20 10
Development 800 990
·Analysis 30 120
·Design Spec 60 20
·Design Review 30 10
·Coding Standard 10 10
·Design 30 20
·Coding 300 420
·Code Review 60 30
·Test 300 360
Reporting 120 120
·Test Report 60 70
·Size Measurement 30 20
·Postmortem & Process Improvement Plan 30 30
Total 940 1120
posted on 2021-03-26 20:08  BuniQ  阅读(147)  评论(3编辑  收藏  举报