201771030104-道彤阳 实验三 结对项目—《西北师范大学疫情防控信息系统》项目报告
内容 | 项目 |
---|---|
课程班级博客链接 | https://edu.cnblogs.com/campus/xbsf/nwnu2020SE |
这个作业要求链接 | https://www.cnblogs.com/nwnu-daizh/p/12521474.htmlml |
我的课程学习目标 | 认真完成学习任务,学习结对编程技巧,提高编程能力 |
这个作业在哪些方面帮助我实现学习目标 | 通过结对编程,掌握结对编程的方法,提高编程能力,熟练GitHub操作 |
结对方学号-姓名 | 201771030108—鲁斌 |
结对方本次博客作业链接 | https://www.cnblogs.com/XuWang-000/p/12581067.html |
本项目Github的仓库链接地址 | https://github.com/daotongyang/EpidemicManagement.git |
任务二
- 对项目博文作业进行阅读并进行评论,评论要点包括:博文结构、博文内容、博文结构与PSP中“任务内容”列的关系、PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异化分析与原因探究,将以上评论内容发布到博客评论区。
- 克隆结对方项目源码到本地机器,阅读并测试运行代码,参照《现代软件工程—构建之法》4.4.3节核查表复审同伴项目代码并记录。
1.概要部分
①代码符合需求和规范说明;
②代码设计考虑周全;
③代码可读性挺好,注释全面;
④每一个功能都是一个函数,容易维护;
⑤每个函数都进行了测试,异常也及时抛出;
2.设计规范部分
①设计遵从已知的设计模式或项目常用的模式;
②没有硬编码或字符串、数字的存在;
③代码没有依赖于某一平台,不会影响将来的移植;
④留着比较多的无用代码;
3.代码规范部分
严格遵循了软件工程编程规范;
4.具体代码部分
①以及对错误函数进行了处理,对于调用的外部函数,检查了返回值和异常;
②参数传递无错误;
③很好的处理了循环问题,不会出现死循环;
④没有实现断言来保证我们认为不变的条件真的得到满足;
⑤对资源的利用,申请,释放处理很好,但没有忧患空间;
5.效能
①代码的效能可观;
②对于系统和网络的调用不会超时;
6.可读性
代码可读性高,注释详细;
7.可测试性
代码无需更新或创建新的单元测试,针对特定领域的开发,可以整理专门的核查表; - 依据复审结果尝试利用github的Fork、Clone、Push、Pull request、Merge pull request等操作对同伴个人项目仓库的源码进行合作修改。
任务三
需求分析
(1)可采集全校各类师生员工疫情信息;
(2)各二级部门疫情防控工作负责人可查看本部门人员疫情汇总,并提供高级查询功能进行多属性组合查询和可视化统计功能;
(3)学校防控办指定负责人登录《西北师范大学疫情防控信息统计》子系统,可浏览所有人员填报汇总数据清单,利用【高级查询】可进行数据组合筛选,系统以图形化方式展示各学院已填报和未填报学生统计情况和关键疫情数据统计情况,可【导出】查询列表的EXCEL文件;
(4)人机交互界面要求GUI界面(WEB页面、APP页面都可);
(5)附加分功能:定时填报提醒
软件设计
- 结构设计
- 程序设计
严格执行力结构设计中提到的方法和技术和环境,对于这次的任务,设计的包,类,jsp如何所示:
- 数据结构
实验二和实验三相差不是特别大,实验二我采用了命令行的形式,但这次是GUI形式,对数据库我也进行了相应的改动,这个增加了疫情的负责人和二级管理部门,我的想法是学院可以查看和修改学生的信息,学生可以查看自己的疫情信息,学校可以查看各学院的教育局可以查看全校的信息。
软件实现及核心功能代码展示
- 核心代码
/**
* 给构造的查询链接赋值参数
* @param page
* @param prepareStatement
* @return
*/
private PreparedStatement setParams(Page<T> page,PreparedStatement prepareStatement){
List<SearchProperty> searchProperties = page.getSearchProperties();
int index = 1;
for(SearchProperty searchProperty : searchProperties){
try {
if(searchProperty.getOperator() != Operator.IN){
prepareStatement.setObject(index++, searchProperty.getValue());
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return prepareStatement;
}
/**
* 构造一般查询语句
* @param type
* @return
*/
private String buildSql(int type) {
// TODO Auto-generated method stub
String sql = "";
switch (type) {
case CURD_ADD:{
String sql1 = "insert into " + StringUtil.convertToUnderLine(t.getSimpleName()) + "(";
Field[] declaredFields = t.getDeclaredFields();
for(Field field : declaredFields){
sql1 += StringUtil.convertToUnderLine(field.getName()) + ",";
}
sql1 = sql1.substring(0,sql1.length()-1) + ")";
String sql2 = " values(null,";
String[] params = new String[declaredFields.length-1];
Arrays.fill(params, "?");
sql2 += StringUtils.join(params, ",") + ")";
sql = sql1 + sql2;
break;
}
case CURD_SELECT:{
sql = "select * from " + StringUtil.convertToUnderLine(t.getSimpleName());
break;
}
case CURD_COUNT:{
sql = "select count(*) as total from " + StringUtil.convertToUnderLine(t.getSimpleName());
break;
}
case CURD_UPDATE:{
sql = "update " + StringUtil.convertToUnderLine(t.getSimpleName()) + " set ";
Field[] declaredFields = t.getDeclaredFields();
for(Field field : declaredFields){
if(!"id".equals(field.getName())){
sql += StringUtil.convertToUnderLine(field.getName()) + " =?,";
}
}
sql = sql.substring(0,sql.length()-1) + " where id = ?";
break;
}
case CURD_DELETE:{
sql = "delete from "+StringUtil.convertToUnderLine(t.getSimpleName())+" where id in(";
break;
}
default:
break;
}
System.out.println(sql);
return sql;
}
/**
* 给构造的查询链接赋值参数
* @param page
* @param prepareStatement
* @return
*/
private PreparedStatement setParams(Page<T> page,PreparedStatement prepareStatement){
List<SearchProperty> searchProperties = page.getSearchProperties();
int index = 1;
for(SearchProperty searchProperty : searchProperties){
try {
if(searchProperty.getOperator() != Operator.IN){
prepareStatement.setObject(index++, searchProperty.getValue());
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return prepareStatement;
}
程序运行
- 登录界面
- 以管理员身份进入,对学生列表进行操作
- 以学生身份进入,查询,删除,修改自己的信息
- 将数据库导出到的Excel中
描述结对的过程
在整个结对过程中,我们都配合的特别好,刚开始在选择工具上双方都比较矛盾,之前我们两个都采用的Python进行编程,这次又采用了Java,好多东西都是新学的,做的比较简陋,但这个学习过程让我们双方都有很大的收获。
此次结对作业的PSP
PSP2.1 | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 30 | 20 |
Estimate | 估计这个任务需要多少时间 | 1448 | 1450 |
Development | 开发 | 100 | 105 |
Analysis | 需求分析(包括学习新技术) | 20 | 20 |
Design Spec | 生成设计文档 | 50 | 40 |
Design Review | 设计复审(和同事审核设计文档) | 40 | 50 |
Coding Standard | 代码规范(为目前的开发指定合适的规范) | 20 | 20 |
Design | 具体设计 | 200 | 195 |
Coding | 具体编程 | 800 | 850 |
Code Review | 代码复审 | 50 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 70 | 65 |
Reporting | 报告 | 50 | 40 |
Test Report | 测试报告 | 10 | 9 |
Size Measurmen | 计算工作量 | 8 | 6 |
Postmortem & Process Imporvement Plan | 事后总结,并提出过程改进计划 | 30 | 20 |
小结
通过这次实验,让我真正感觉到了老师所说的1+1>2,在整个项目编程中,我们双方配合的都很有默契,彼此都不断的发挥着自己的想法,但毕竟的初次结对编程,还有很多需要学习的东西,希望在以后的学习中,可以有更多这样的机会去锻炼和学习。