Word Count 第四周小组作业

GitHub地址

GitHub 地址为:https://github.com/ReWr1te/WcPro

PSP 表格 

PSP2.1

PSP阶段

预估耗时

(分钟)

实际耗时

(分钟)

Planning

计划

20 20

· Estimate

· 估计这个任务需要多少时间

20 20 

Development

开发

880  1160

· Analysis

· 需求分析 (包括学习新技术)

60 80

· Design Spec

· 生成设计文档

30 30

· Design Review

· 设计复审 (和同事审核设计文档)

30 60

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

40 30 

· Design

· 具体设计

180 240 

· Coding

· 具体编码

180 240 

· Code Review

· 代码复审

120 120

· Test

· 测试(自我测试,修改代码,提交修改)

240 360

Reporting

报告

100  70

· Test Report

· 测试报告

30  30

· Size Measurement

· 计算工作量

10  10

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

60 30 
 

合计

1000 

 1250

 

代码实现

我主要负责其他一些杂模块的编写,也进行了对输入模块的重构和优化。

主程序就是对于划分的三块——输入、处理、输出类实例化并调用即可。

import java.util.HashMap;

public class WcPro {
    public static void main(String[] args) {

        CommandParser commandParser = new CommandParser();
        ContentParser contentParser = new ContentParser();
        ResultWriter resultWriter = new ResultWriter();


        String content = commandParser.parseCommand(args);
        HashMap<String, Integer> result = contentParser.parseContent(content);
        resultWriter.writeResult(result);
    }
}

主要的任务量在于研究GUI界面实现,发现现有的输入模块无法实现相关的扩展,于是对输入模块进行了重构。

主要的重构在于,对于输入的参数统一处理,处理为输入文件的绝对路径。

public String paraHandling(String[] args) {
    String path = null;
    if (args.length == 0) {
        System.out.println("Please enter parameter!");
        return null;
    } else if (args.length > 1) {
        System.out.println("Too many parameters! Please input just one parameter!");
        return null;
    } else {
        if (args[0].equals("-x")) {
            Frame frame = new Frame();
            FileDialog openFile = new FileDialog(frame, "打开一个txt文件", FileDialog.LOAD);
            openFile.setVisible(true);
            String dirName = openFile.getDirectory();
            String fileName = openFile.getFile();
            if ((dirName == null) || (fileName == null)) {
                System.out.println("You didn't choose a file!");
                frame.dispose();
                return null;
            } else {
path
= dirName + fileName; frame.dispose(); return path; } } if (args[0].indexOf("*.") != -1) { System.out.println("Too many files! Please input just one file!"); return null; } if (!args[0].endsWith(".txt")) { System.out.println("Wrong file type! Please input .txt files!"); return null; } if (args[0].indexOf(":") != -1 || args[0].indexOf("/") != -1 || args[0].indexOf("\\") != -1) { path = args[0]; } else { path = getPath(args[0]); } return path; } }

先对输入参数数量为0或者大于1的情况进行处理,然后对一个参数进行判断。判断是否为“-x”,如果是,启动GUI。判断可能存在的错误包括使用*.txt之类的参数或者非txt文件名。如果参数验证成功,则会判断是否为绝对路径,如果为绝对路径则会直接使用。否则会加上当前运行目录,生成绝对路径。

对于一些原来的函数传参进行优化,使得模块耦合度降低,更加易于维护。

测试用例设计

主函数方面比较简单,没有设计白盒测试,设计了黑盒测试。主要是对各种输入情况来研究是否正常输出。

此处测试比较单一,与测试输入模块比较相似。

测试输入文件 测试说明 测试结果
test0.txt 相对路径文件测试
test1.txt 相对路径文件测试
test2.txt 相对路径文件测试
test3.txt 相对路径文件测试
test4.txt 相对路径文件测试
test5.txt 相对路径文件测试
test0.txt(绝对路径) 绝对路径文件测试
test1.txt(绝对路径) 绝对路径文件测试
test2.txt(GUI测试) GUI获取绝对路径文件测试

然后因为对输入模块进行了重构,所以输入模块的测试也进行了重构,修改文件路径为绝对路径。相关测试设计可参照田诗园同学的WcPro项目(WordCount优化)

进行了重构、优化,使得自动化测试可以在每台机器上运行。

测试用例的运行截图

 静态测试开发规范(拓展任务)

使用了《阿里巴巴Java开发手册》的开发规范。推荐类型规范主要是告诉我们如何编写更具有易读性和扩展性的代码。对于如何写好代码的编码技巧,非常有用。以此规范作为例子:

【推荐】如果模块、接口、类、方法使用了设计模式,在命名时体现出具体模式。 说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计理念。

在之前组员的代码中paraHandling方法就可以看出是一个处理参数的方法,但是看过代码之后,感觉其只是实现了一个参数的判断功能。而对于参数判断功能单独拆分出来后,加入GUI会使代码想法变得不统一。因此最后我们对这个模块进行了重构。

静态代码检查工具为Alibaba Java Coding Guidelines,与之前使用的《阿里巴巴Java开发手册》相适应。

GitHub地址为:https://github.com/alibaba/p3c 我下载了Eclipse的插件。

需要改动的很多,比如魔法值的情况,一般是不允许出现魔法值的。但是在这里有些繁琐的判断,在魔法值使用下可以简化很多。因此暂时没有做修改。其他的有注释规范,不允许行内注释、必须使用/** xxx */注释方法。一定程度上统一了代码的格式。

小组代码问题有一些,因为大家对于Java不是那么熟悉,对于工程也不熟悉,所以在一些细节处理上不够好。模块之间的设计,有一些优化空间。

组内代码分析

经过组内代码统一评审,发现了一些代码存在的共同问题:

  • 代码没加作者信息;
  • 方法开头没使用javadoc形式的注释;
  • 常量未定义直接在代码中使用;
  • 大量使用行尾注释;
  • 未及时清理不用的代码段;
  • if判定条件后没写大括号。

性能分析和优化(高级任务)

经过试验,我们发现当txt文件的字符数达到千万级别时能给程序带来压力。我们小组使用了JavaScript库JQuery改名文件jQuery.txt作为测试数据集,包含24,025,398个字符,307,981行。

同行评审过程描述

角色分工:

  • 主持人&记录员:田诗园
  • 讲解员:邱利光 沃锦文 王启萌 田诗园
  • 评审员:邱利光 沃锦文 王启萌 田诗园
  • 作者:邱利光 沃锦文 王启萌 田诗园

评审目的:

  • 评定代码对于性能需求的满足程度。
  • 对程序进行性能优化。

评审意见收集:

  • 代码并无明显缺陷。
  • 代码性能可以继续优化。

评审结果

  • 正则表达式效率较慢,可以用状态机来提取单词。
  • 考虑到程序对查找的性能要求比较高,单词统计我们采用HashMap来存储。当数据容量较少时其内部实现为一个链表,当数据量较大时,自动改用二叉树进行存储,有效提高了查询效率。
  • 输出单词时,改变原来的每个单词打开一次文件的做法,只打开一次文件,全部输出后关闭文件流,提高了IO速度。

性能分析

  • 正则表达式效率较慢,可以用状态机来提取单词。
  • 考虑到程序对查找的性能要求比较高,单词统计我们采用HashMap来存储。当数据容量较少时其内部实现为一个链表,当数据量较大时,自动改用二叉树进行存储,有效提高了查询效率。
  • 输出单词时,改变原来的每个单词打开一次文件的做法,只打开一次文件,全部输出后关闭文件流,提高了IO速度。

性能优化

  • 使用状态机代替正则式分词提高效率。
  • 把多次输出改为一次输出提高IO速度。

GUI界面(附加题)

完成了基本功能之后,我负责其他这一部分模块,包括主类的编写和测试以及其他的功能。因此决定完成此附加题,添加-x参数打开GUI选择文件对话框。在实现功能的时候,我们发现处理参数的模块CommandParser类的内部结构无法实现-x参数这种参数扩展。因此重构了此部分代码,重写的相关测试并加入了附加题要求的功能。

程序运行截图:

 

posted @ 2018-04-08 23:58  Lovegood  阅读(167)  评论(1编辑  收藏  举报