这个作业属于哪个课程 | 福大20春软工S班 |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) |
这个作业的目标 | 掌握github的使用,掌握单元测试 |
作业正文 | 即本文 |
其他参考文献 | 百度、博客园、CSDN文章 |
一、github仓库地址
疫情统计系统
二、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 80 |
Estimate | 估计这个任务需要多少时间 | 30 | 45 |
Development | 开发 | 2200 | 2530 |
Analysis | 需求分析 (包括学习新技术) | 260 | 290 |
Design Spec | 生成设计文档 | 80 | 90 |
Design Review | 设计复审 | 50 | 50 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 80 | 120 |
Design | 具体设计 | 200 | 180 |
Coding | 具体编码 | 900 | 1150 |
Code Review | 代码复审 | 120 | 110 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 130 |
Reporting | 报告 | 200 | 170 |
Test Repor | 测试报告 | 110 | 120 |
Size Measurement | 计算工作量 | 30 | 50 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 90 | 70 |
合计 | 2290 | 2655 |
三、解题思路描述
浏览完了题目,大体的思路还是比较清晰的,如下图;其中涉及到命令行的处理以及单元测试是我之前没有接触过的,花费了很多的时间去学习
四、设计实现过程
(字太多有点模糊,建议放大观看)
五、代码说明
首先是judgeCommandLine函数,用于解析命令行,主要是用if判断,都大同小异,放几个典型的上来
最简单的判断开头是否为list
/*
* 判断开头是否为list
*/
if(!str[0].equals("list"))
{
System.out.println("命令行错误,开头非list错误");
System.exit(0);
}
运用正则来判断传入的路径是否正确
for(int i=1;i<str.length;i++)
{
/*
* 判断-log 以及提取出log_route
*/
if(str[i].equals("-log"))
{
if(str[++i].matches("^[A-z]:\\(.+?\\)*$"))
{
log_route=str[i];
}
else
{
System.out.println("命令行错误,文件路径未填写或错误");
System.exit(0);
}
}
判断-date得到排序好的日志列表和我们读入的或者默认的时间,以便于后续输出
/*
* 判断-date,得到log_list和log_need
*/
if(str[i].equals("-date"))
{
if((i+1)==str.length)
{
getLogList(log_route);
log_need=log_list[log_list.length-1];
}
else if(str[i+1].equals("-log")||str[i+1].equals("-out")
||str[i+1].equals("-type")||str[i+1].equals("-province"))
{
getLogList(log_route);
log_need=log_list[log_list.length-1];
}
else
{
if(isLegalDate(str[++i]))
{
getLogList(log_route);
log_need=str[i]+".log.txt";
}
else
{
System.out.println("命令行错误,日期格式有误");
System.exit(0);
}
}
}
province_select数组用来标记一个省份应不应该输出
/*
* 判断-province 如果存在province_select置为1
*/
if(str[i].equals("-province"))
{
for(int j=1;j<=province_name.length;j++)
{
if((i+j)<str.length)//-province如果是最后一个指令,直接退出
{
int temp=0;//用来判断省份名称是否输入正确
if(str[i+j].equals("-log")||str[i+j].equals("-out")
||str[i+j].equals("-date")||str[i+j].equals("-type"))
{
break;
}
for(int k=0;k<province_name.length;k++)
{
if(str[i+j].equals(province_name[k]))
{
temp=1;
if(k==0)
province_select[0]=1;
if(province_select[0]==-1)
province_select[0]=0;
province_select[k]=1;
break;
}
}
if(temp==0)
{
System.out.println("命令行错误,-province格式有误!");
System.exit(0);
}
}
else break;
}
}
}
下面是辅助judgeCommandLine完成的函数,也是不可或缺的。判断日期是否合法的函数比较简单我就没放上来。最关键的一个函数就是将得到的日志列表进行排序
/*
* 得到log_route下的所有文件名
*/
public static void getLogList(String str) {
log_list=new File(str).list();
for (int i=0;i<log_list.length-1;i++){//将获取到的文件名进行排序
for (int j=0;j<log_list.length-i-1;j++) {
if(log_list[j].compareTo(log_list[j+1])>0){
String temp=log_list[j];
log_list[j]=log_list[j+1];
log_list[j+1]=temp;
}
}
}
}
接下来是文件读取和处理部分
按行读取文本内容部分,并将之传入文本处理函数进行处理,对之使用正则匹配,并传入相应的函数中处理,举两个例子
/*
* 读取文本内容
*/
public static void getTextContent(String str) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader
(new FileInputStream(new File(str)), "UTF-8"));
String text_content = null;
while ((text_content = br.readLine()) != null) { //按行读取文本内容
if(!text_content.startsWith("//")) //遇到“//”不读取
processingText(text_content);
}
br.close();
} catch (Exception e) {
// TODO: handle exception
}
}
/*
* 疑似患者确诊
*/
public static void diagnoseSP(String str) {
// TODO 自动生成的方法存根
String[] str_arr=str.split(" "); //字符串数组以空格分割成多个字符串
int i;
int n=Integer.valueOf(str_arr[3].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(i=0;i< province_name.length;i++)
{
if(str_arr[0].equals(province_name[i]))
{ //第一个字符串为省份
province_num[0][1]-=n; //全国疑似患者人数减少
province_num[0][0]+=n; //全国感染患者人数增加
province_num[i][1]-=n; //该省份疑似患者人数减少
province_num[i][0]+=n; //该省份感染患者人数增加
if(province_select[0]==-1) //省份处于未指定状态
province_select[i]=1; //需要将该省份列出
break;
}
}
}
最后是文件输出部分
fwriter=new FileWriter(str);
int i,j,k;
if(province_select[0]==-1)//表示未指定省份
province_select[0]=1;
for(i=0;i<province_name.length;i++)
{
if(province_select[i]==1)
{
fwriter.write(province_name[i] + " ");
for(j=0;j<type_num.length;j++)
{
for(k=0;k<type_num.length;k++)
{
if(type_num[k]==j+1)
{
fwriter.write(type_name[k] + province_num[i][k] + "人 ");
break;
}
}
}
fwriter.write("
");
}
}
fwriter.write("// 该文档并非真实数据,仅供测试使用");
六、单元测试截图和描述
写了十几个测试用例,因为太多固只上传其中一部分
七、单元测试覆盖率优化和性能测试
八、我的代码规范的链接
九、心路历程与收获
本次作业十分复杂,花费了大量的时间去学习新的知识新的技术,特别是github的学习和使用,单元测试和性能测试等等。但是我觉得付出是值得的,因为我同样收获了很多的东西。从一开始的无从下手,每天看着学习资料脑子里一点想法都没有,到后面渐渐找到方向,慢慢进入正轨,虽然学的很慢,但确实是有学到东西的。也对开发一个项目的很多具体流程有了更加清晰和深刻的认识。特别是《构建之法》这本书,我觉得这真的是一本非常棒的书,能学到许多东西。明白了代码规范和测试的重要性。
十、第一次作业中技术路线图相关的5个仓库
1.大前端工具集
简介:这个仓库提供了很多前端需要了解的工具以及相应的技术,以及一些很生动炫酷的例子,也包括前端面试的一些经验与技巧。
2.前端开发者手册
简介:这个仓库概述并讨论了前端工程的实践: 该如何学习以及实践时该使用什么工具。为潜在以及正在实践的前端开发人员提供一个包括学习资料和开发工具的专业资源
3.ES6入门教程笔记
简介:ES6的很多部分其实并不好学,不是那么容易理解,这里面列出了一些难点,对一些知识点的更详细的解析,有助于学好ES6。
4.每个JavaScript工程师都应懂的33个概念
简介:这个项目是为了帮助开发者掌握 JavaScript 概念而创立的。它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南。
5.基于vue的后台管理系统
简介:此项目是 vue + element-ui 构建的后台管理系统,是后台项目node-elm 的管理系统,所有的数据都是从服务器实时获取的真实数据,具有真实的注册、登陆、管理数据、权限验证等功能。