软工实践寒假作业(2/2)

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2020SPRINGS
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/2020SPRINGS/homework/10287
这个作业的目标 完成题目要求,试着使用git、JUnit等开发工具
作业正文 ....
其他参考文献 ...

一、 github仓库地址

https://github.com/qiyuan129/InfectStatistic-main

二、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 40
Estimate 估计这个任务需要多少时间 1165 1580
Development 开发 720 1320
Analysis 需求分析 (包括学习新技术) 60 240
Design Spec 生成设计文档 60 60
Design Review 设计复审 30 60
Coding Standard 代码规范 (为目前的开发制定合适的规范) 10 15
Design 具体设计 60 90
Coding 具体编码 600 600
Code Review 代码复审 30 30
Test 测试(自我测试,修改代码,提交修改) 180 240
Reporting 报告 60 60
Test Repor 测试报告 30 30
Size Measurement 计算工作量 15 20
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30 150
合计 1165 1580

三、解题思路描述

先大概看一下题目要求中是如何输入输出,然后仔细看看提供的可能输入的参数及组合,弄清楚大致需要有哪些功能。

然后再进行仔细地阅读,思考后在纸上写下大概会有哪些类,各个类大致应该有哪些属性及方法,类之间的关系是如何,类间大致会如何调用,由此得到一个初步的类图。

之后再针对题目要求的每个大致功能点,思考(可以画出)功能实现的流程,中间大致会使用到哪些类,类方法的调用情况等。

最后按照上面得到的初步的设计文档开始编程。

这里列出经编程中稍加修改后的最终的类图(主要是类属性和方法较初版有变化):

四、设计实现过程

程序执行的流程图如下:

由日志录入信息的流程图如下:

使程序满足题目输出要求的流程如下:

五、代码说明

日志的分析代码(拆分每行日志,根据包含关键词的不同情况使用对应的函数进行处理):

fis = new FileInputStream(logFile);
            BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));

            String line = null;
            while ((line = br.readLine()) != null) {
                //注释不处理
                if (line.contains("//")) {
                    continue;
                }
                //下面是日志中八种情况的处理
                if (line.contains("新增") && line.contains("感染")) {
                    addInfected(line);
                    continue;
                }
                if (line.contains("新增") && line.contains("疑似")) {
                    addSuspected(line);
                    continue;
                }
                if (line.contains("流入") && line.contains("感染")) {
                    flowInfected(line);
                    continue;
                }
                if (line.contains("流入") && line.contains("疑似")) {
                    flowSuspected(line);
                    continue;
                }
                if (line.contains("死亡")) {
                    addDead(line);
                    continue;
                }
                if (line.contains("治愈")) {
                    addCured(line);
                    continue;
                }
                if (line.contains("确诊")) {
                    suspectedToInfected(line);
                    continue;
                }
                if (line.contains("排除")) {
                    suspectedToHealthy(line);
                    continue;
                }
            }

            br.close();
            fis.close();

示例:处理疑似患者流动的函数(分析、取得数据,录入数据,令有出现的省份标记为true,后面输出时会用到)

private void flowSuspected(String line) {
        String[] words = line.split(" ");
        String province1Name = words[0];
        String province2Name = words[3];
        String numberString = words[4];
        int number = Integer.parseInt(numberString.substring(0, numberString.length() - 1));

        dailyInfos.get(province1Name).changeSuspected(-number);
        dailyInfos.get(province2Name).changeSuspected(number);
        country.getProvince(province1Name).hasOccurred = true;
        country.getProvince(province2Name).hasOccurred = true;
    }

统计一省信息的代码(思路:将Province对象中存放的指定日期及之前的疫情数据全部相加)(全国疫情就是当天各省总疫情情况相加之和):

public DailyInfo getStatistic(LocalDate endDate) {
        //未进行统计就计算一遍
        if (totalInfo == null) {
            DailyInfo totalInfo = new DailyInfo(endDate);

            for (DailyInfo info : dailyInfos) {
                //只处理指定日期当天以及之前的日志
                if (info.getDate().isBefore(endDate) || info.getDate().isEqual(endDate)) {
                    totalInfo.add(info);
                }
            }

            this.totalInfo = totalInfo;
            return totalInfo;
        } else {
            return this.totalInfo;
        }
    }

获取各省统计信息的代码(由各省对象得到统计信息,最后加入到一张HashMap中,方便使用):

public HashMap<String, DailyInfo> getAllProvincesInfo(LocalDate endDate) {
        if (totalStatistics == null) {
            HashMap<String, DailyInfo> totalInfos = new HashMap<>();

            for (String provinceName : Country.PROVINCES) {
                Province province = provincesMap.get(provinceName);
                DailyInfo provinceStatistic = province.getStatistic(endDate);
                totalInfos.put(provinceName, provinceStatistic);
            }

            this.totalStatistics = totalInfos;
            return totalInfos;
        } else {
            return totalStatistics;
        }
    }

六、单元测试

部分关键代码测试:

获得统计总数据测试

从日志读取信息,录入到Province中,尝试读取录入的数据

实际样例测试
基于题目example中给出的3个Log文件(因为在IDEA里测试用相对路径不知道为什么会报路径不存在错误,所以输入输出写死都成了绝对路径)

String[] args1=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\1.txt " +
                "-date 2020-01-22 ").split(" ");
        argsList.add(args1);

        String[] args2=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt " +
                "-date 2020-01-27 -province 福建 河北 -type cure ip sp").split(" ");
        argsList.add(args2);

        String[] args3=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\1.txt "+
                "-date 2020-01-27").split(" ");
        argsList.add(args3);

        String[] args4=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt "+
                "-date 2020-01-25").split(" ");
        argsList.add(args4);

        String[] args5=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt "+
                "-type ip sp dead").split(" ");
        argsList.add(args5);

        String[] args6=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt ").split(" ");
        argsList.add(args6);

        String[] args7=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt "+
                "-province 福建 安徽 重庆").split(" ");
        argsList.add(args7);

        String[] args8=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt "+
                "-province 湖北 安徽 重庆 全国").split(" ");
        argsList.add(args8);

        String[] args9=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt "+
                "-province 福建 安徽 重庆").split(" ");
        argsList.add(args9);

        String[] args10=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt "+
                "-province 福建 安徽 重庆 -date 2020-01-27 ").split(" ");
        argsList.add(args10);

        String[] args11=("-log C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\log -out C:\Users\62706\Documents\GitHub\InfectStatistic-main\221701225\src\result\2.txt "+
                "-province 福建 安徽 重庆 -date 2020-01-27 -type ip sp dead").split(" ");
        argsList.add(args11);

测试结果

七、覆盖率、性能测试

通过减少重复代码等,最后达到较高的覆盖率

性能测试结果,不懂得怎么优化。。

八、代码规范

https://github.com/qiyuan129/InfectStatistic-main/blob/master/221701225/codestyle.md

九、心路历程与收获

对我这种好久没有写过”大作业“了的人来说,这次作业的量还是蛮大的。开始敲代码前,看到作业要求以及微信群里助教补充的各种要求,还是感到有些复杂。

在编写代码前的准备阶段,我深深感到自己分析需求和编写文档的能力不足。在画类图时,我会为一个属性或是一个功能的实现该放在哪个类中的困惑。在思考/写下功能实现的流程图时,数次觉得之前的类图不合理,返回去修改,这浪费了很多时间。

这说明我对软件开发中面向对象设计与分析的方法与步骤还不熟悉,需要以后改进。

此外,这次学习到的回归测试的概念,覆盖率测试、性能测试的基本概念及方法都是很有价值的内容,特别是性能测试这块,感觉里面的水很深,以后有机会一定要好好学学。

十、技术路线图相关库:

1.springboot-learning

https://github.com/ityouknow/spring-boot-leaning/tree/gitbook_column2.0
很好的学习springboot的项目,示例代码很精简,和知识点可以很好地对应起来

2.springboot-examples

https://github.com/ityouknow/spring-boot-examples
Spring Boot 使用的各种示例,以最简单、最实用为标准,此开源项目中的每个示例都以最小依赖,最简单为标准,帮助初学者快速掌握 Spring Boot 各组件的使用

3.CS-Notes

https://github.com/CyC2018/CS-Notes
计算机基础等知识的很好的总结笔记

4.redisdoc

https://github.com/huangz1990/redis
Redis Command Reference》全文的中文翻译版。

5.JMeter

https://github.com/apache/jmeter
一款开源的java性能测试工具

原文地址:https://www.cnblogs.com/ccqy/p/12330809.html