软工实践寒假作业(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性能测试工具