201771030123-王爽 实验三 软件工程结对项目—《西北师范大学疫情防控系统》项目报告

项目 内容
课程班级博客链接 2020年春软件工程课程班(2017级计算机科学与技术)
这个作业要求链接 实验三 软件工程结对项目
我的课程学习目标 (1)体验软件项目开发中的两人合作,练习结对编程(Pair programming)。
(2)掌握Github协作开发程序的操作方法。
这个作业在哪些方面帮助我实现学习目标 (1)阅读《构建之法》第3-4章内容,学习了解结对编程的相关内容。
(2)通过结对编程的过程去熟悉GitHub协作开发的各种操作。
结对方的学号姓名 <201771030117-祁甜>
结对方的博客作业连接 https://www.cnblogs.com/viqt/p/12588543.html
本项目的仓库链接 https://github.com/Gu19901212/Partner.git

一.对结对方《实验二 软件工程个人项目》的项目成果进行评价

  (1)对项目博文作业进行阅读并进行评论

  结对方博客链接

  结对方项目仓库链接

    评论截图如下图:

  (2)克隆结对方项目源码,阅读并测试运行代码,复审同伴项目代码并记录。

 代码复审核查表 

1.概要部分
  1)代码能符合需求和规格说明么? 能,系统可以实现对疫情的上报与统计
  2)代码设计是否有周全的考虑? 否,还需要继续完善
  3)代码可读性如何? 可读,每个类都有特定功能的注释
  4)代码容易维护吗? 比较容易维护
  5)代码的每一行都执行并检查了吗? 每一行都检查了但没有单步执行,只是整体执行

2.设计规范部分
  1)设计是否遵从已知的设计模式或项目中常用的模式? 是的,是已知的设计模式,比较容易掌握
  2)有没有硬编码或字符串/数字等存在? 没有
  3)代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到Win64)? 不会影响
  4)开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现? 有的,存在有的类似功能可以调用
  5)有没有无用的代码可以清除? 没有

3.代码规范部分
   修改的部分符合代码标准和风格么? 符合

4.具体代码部分
  1)有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常? 有的有出错处理,有的没有,没有异常
  2)参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数? 参数传递没有错误,字符串的长度是字节的长度,是以1开始的
  3)边界条件是如何处理的?switch语句的default分支是如何处理的?循环有没有可能出现死循环? 设有判断语句,不会出现死循环
  4)有没有使用断言(Assert)来保证我们认为不变的条件真的得到满足? 没有
  5)对资源的利用,是在哪里申请,在哪里释放的?有无可能存在资源泄露(内存、文件、各种GUI资源、数据访问的连接,等等)?有没有优化空间? color=gray
  6)数据结构中有没有用不到的元素? 没有

5.效能
  1)代码的效能(Performance)如何? 基本达到任务要求
  2)代码中,特别是循环中是否有明显可优化的部分(C++中反复创建类,C#中 string 的操作是否能用StringBuilder 来优化)? 没有
  3)对于系统和网络调用是否会超时?如何处理? 目前没有出现超时,如果出现如何处理还需要寻找方法

6.可读性
   代码可读性如何?有没有足够多的注释? 可读性可以,有足够多的注释

7.可测试性
   代码是否需要更改或创建新的单元测试? 不需要

  (3)依据复审结果尝试利用github的Fork、Clone、Push、Pull request、Merge pull request等操作对同伴个人项目仓库的源码进行合作修改。

    1)到同伴仓库下使用fork,并在自己的仓库中查看,截图如下:

    2)使用clone将从同伴那里fork过来的项目下载到本地,截图如下:


    3)使用push、pull request对同伴的代码进行修改,下面的截图是我通过push更新了一些文件再pull request给同伴,她再merge pull request的记录如下:

二.采用两人结对编程方式,结合我校师生疫情每日上报系统使用体验,设计开发一款符合我校疫情防控工作需求的信息系统

  (1)需求分析陈述

  • 非功能性需求
        现在由于新冠状病毒的疫情,各个城市的学校都一致延迟开始时间,但是虽然延迟时间,但学校也希望大家能早日返校,所以在此之前学校也要求我们每天都填写疫情上报表。在所有人都填写了之后,希望能根据学校的要求清晰的查看所有职工及学生的情况,所以现在设计开发一款符合我校疫情防控工作需求的信息系统

  • 功能性需求
    • (1)可采集全校各类师生员工疫情信息;
    • (2)各二级部门疫情防控工作负责人可查看本部门人员疫情汇总,并提供高级查询功能进行多属性组合查询和可视化统计功能;
    • (3)学校防控办指定负责人登录《西北师范大学疫情防控信息统计》子系统,可浏览所有人员填报汇总数据清单,利用【高级查询】可进行数据组合筛选,系统以图形化方式展示各学院已填报和未填报学生统计情况和关键疫情数据统计情况,可【导出】查询列表的EXCEL文件;
    • (4)人机交互界面要求GUI界面(WEB页面、APP页面都可);
    • (5)附加分功能:定时填报提醒

  对于这些需要实现的功能来说,由于我们团队在实验二中,我选的是一类,同伴选的是二类。相对来说,同伴的实验二的项目跟此次的项目比较贴切,所以一开始我们是暂定为,在她的项目上进行修改,就是添加一些功能、页面设计等。而我之前实验二做的是一类,对可视化已经数据转储的知识已经有一定的熟悉,所以我们的暂定分工为:同伴负责在他的实验二源程序上添加教师填报的相关功能,我负责对收集的信息的可视化以及列表的导出Excel功能进行实现,最后两个人再讨论对于交互界面的处理。

  (2)软件设计说明

    设计思路说明:一开始我们是想按照需求分析的功能依次实现的,但是实际情况与预期不同,一直不能达到预期效果,在最后的时候我们决定导出Excel和数据可视化与填报系统分开实现,使用项目yiqing来实现教师学生填报疫情信息以及各防空办查看总体信息,使用项目yiqingToExcel来实现从数据库读取信息并且导出Excel已经将读取的信息绘制柱状图。具体类实现如下:

  • DBhelper.java——连接MySQL数据库的工具类
  • Yiq.java——数据库中yiqing表的实体类
  • YiqService.java——读取数据库中的表的服务类
  • FromDbToExcel.java——将数据库中的数据导出Excel

  • BaseDao.java——数据库操作基础类,利用泛型和反射机制来抽象数据库基本的增删该查操作;
  • (2)CollegeadminServlet.java——各二级部门疫情防控工作负责人查看本学院学生信息;
  • (3)LoginServlet.java——控制不同身份的人登录;
  • (4)SchoolOfficeServlet.java——学校防疫办获取各学院已经提交的学生和老师的疫情信息;
  • (5)StudentServlet.java——各二级部门疫情防控工作负责人查看本学院老师和学生的疫情信息并提交给学校防疫办;
  • (6)yiqingServlet.java——学生填报疫情信息以及控制条件。
    isEffectiveDate(Date nowTime, Date startTime, Date endTime)函数——控制学生在每天十点以前填报疫情情况,如果在十点以前返回true,否则返回false。
  • yiqingTeacherServlet.java——老师填报疫情信息以及控制条件。
  • yiqingDao.java——各二级部门疫情防控工作负责人提交本学院师生疫情信息后对数据库进行修改;

    类之间的关系:在项目yiqing中,用LoginServlet.java来控制不同身份的人登录,分为老师,学生,学院负责人,学校防空办负责人。登录之后根据身份不同可进行填报信息,进行不同的操作。对于学生和老师就是通过yiqingServlet.java、yiqingTeacherServlet.java两个类来支撑填报信息以及控制条件,学院负责人则是可查看学院师生疫情情况,也就是SchoolOfficeServlet.java这个类支撑的,校防空办的负责人则可以好看所有的的疫情情况;在项目yiqingToExcel中,就是创建实体类(Yiq.java),然后连接数据库(DBhelper.java),之后就是进行数据库服务类(YiqService.java)以及导出和可视化类(FromDbToExcel.java)的实现

  总的来说,我们此次的项目能够达到的功能如下:

    (1)全校师生均可填报疫情信息;
    (2)各二级部门疫情防控工作负责人可查看本部门人员疫情汇总;
    (3)学校防空办指定负责人登录《西北师范大学疫情防控信息统计》子系统,可浏览所有人员填报数据清单;
    (4)网页上更新数据库之后就再从数据库中读取表格内容进行可视化和导出Excel处理;
    (5)人机交互使用web页面;

  主要代码:

public class YiqService {
	/**
	 * 查询数据库中yiqing表中所有的数据
	 */
	public static List<Yiq> getAllByDb() {
		List<Yiq> list = new ArrayList<Yiq>();
		DBhelper db = new DBhelper();
		String sql = "select d.id,d.name1,d.college,d.class1,d.date,d.place,d.wuhan,d.hubei,d.wuhancontact,d.hubeicontact,d.back,d.suspected,d.confirm,d.state from yiqing d";
		ResultSet rs = db.Search(sql, null);
		try {
			while (rs.next()) {
				int id = rs.getInt("id");
				String name1 = rs.getString("name1");
				String college = rs.getString("college");
				String class1 = rs.getString("class1");
				Date date = rs.getDate("date");
				String place = rs.getString("place");
				String wuhan = rs.getString("wuhan");
				String hubei = rs.getString("hubei");
				String wuhancontact = rs.getString("wuhancontact");
				String hubeicontact = rs.getString("hubeicontact");
				String back = rs.getString("back");
				String suspected = rs.getString("suspected");
				String confirm = rs.getString("confirm");
				String state = rs.getString("state");
				
				list.add(new Yiq(id,name1,college,class1,date,place,wuhan,hubei,wuhancontact,hubeicontact,back,suspected,confirm,state));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}

        /**
	 * 实现数据导出Excel和数据可视化主程序
	 */
public static void main(String[] args) {
		try {
			WritableWorkbook wwb = null;
			// 创建可写入的Excel工作簿
            String fileName = "F://test1//yiqing.xls";
            File file=new File(fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
          //以fileName为文件名来创建一个Workbook
            wwb = Workbook.createWorkbook(file);
            
         // 创建工作表
            WritableSheet ws = wwb.createSheet("Test Shee 1", 0);
            
          //查询数据库中所有的数据
            List<Yiq> list= YiqService.getAllByDb();
            //要插入到的Excel表格的行号,默认从0开始
            Label Id= new Label(0, 0, "学号");//表示第
            Label name= new Label(1, 0, "姓名");
            Label college= new Label(2, 0, "班级");
            Label class1= new Label(3, 0, "班级");
            Label wuhan= new Label(4, 0, "武汉籍");
            Label hubei= new Label(5, 0, "湖北籍");
            Label wuhancontact= new Label(6, 0, "武汉接触史");
            Label hubeicontact= new Label(7, 0, "湖北接触史");
            Label back= new Label(8, 0, "是否返校");
            Label confirm= new Label(9, 0, "疑似");
            Label state= new Label(10, 0, "确诊");
            
            ws.addCell(Id);
            ws.addCell(name);
            ws.addCell(college);
            ws.addCell(class1);
            ws.addCell(wuhan);
            ws.addCell(hubei);
            ws.addCell(wuhancontact);
            ws.addCell(hubeicontact);
            ws.addCell(back);
            ws.addCell(confirm);
            ws.addCell(state);
            
            
            
            for (int i = 0; i < list.size(); i++)
            {
            	
            	Label Id_i= new Label(0, i+1, list.get(i).getId()+"");
            	Label Name_i= new Label(1, i+1, list.get(i).getName1()+"");
            	Label college_i= new Label(2, i+1, list.get(i).getCollege()+"");
            	Label class1_i= new Label(3, i+1, list.get(i).getClass1()+"");
            	Label wuhan_i= new Label(4, i+1, list.get(i).getWuhan()+"");
            	Label hubei_i= new Label(5, i+1, list.get(i).getHubei()+"");
            	Label wuhancontact_i= new Label(6, i+1, list.get(i).getWuhancontact()+"");
            	Label hubeicontact_i= new Label(7, i+1, list.get(i).getHubeicontact()+"");
            	Label back_i= new Label(8, i+1, list.get(i).getBack()+"");
            	Label confirm_i= new Label(9, i+1, list.get(i).getConfirm()+"");
            	Label state_i= new Label(10, i+1, list.get(i).getState()+"");
            	
            	
            	
            	ws.addCell(Id_i);
            	ws.addCell(Name_i);
            	ws.addCell(college_i);
            	ws.addCell(class1_i);
            	ws.addCell(wuhan_i);
            	ws.addCell(hubei_i);
            	ws.addCell(wuhancontact_i);
            	ws.addCell(hubeicontact_i);
            	ws.addCell(back_i);
            	ws.addCell(confirm_i);
            	ws.addCell(state_i);
            }
          //写进文档
            wwb.write();
           // 关闭Excel工作簿对象
            System.out.println("数据导出成功!");
            wwb.close();
		}catch (Exception e) {
			 // TODO Auto-generated catch block
            e.printStackTrace();
		}
		JFrame frame=new JFrame("疫情统计表");
		frame.setLayout(new GridLayout(2,2,10,10));
		frame.add(new FromDbToExcel().getChartPanel());   //添加柱形图
		frame.setBounds(0, 0, 900, 800);
		frame.setVisible(true);
	}

  (3)程序运行

  此次项目的功能图如下:

  运行界面:

  学生登录之后进行信息填写并且可看到填报提醒:



  学生上报疫情信息成功!:


  如果当天重复提交会出现下面信息,提醒学生当天已上报过了:


  各二级部门负责人可查看本学院学生上报的疫情情况:


  点击提交可向学校防空部门提交该学院信息,提交成功:


  也可查看本学院教职工的上报的疫情信息并上报到学校:



  还可查看本学院学生的一些信息及联系电话:


  学校防空办负责人登录后可查看全校学生及老师上报的疫情信息:



  网页更新数据库之后运行项目yiqingToExcel,可以得到导出的Excel文件以及可视化柱状图:


  (4)结对交流过程:

  在此次结对编程中我们使用的是qq进行交流,下面是交流的截图:

  (4)上传项目到GitHub:

  (5)此次项目的PSP展示:

PSP2.1 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 30 25
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 30 30
Development 开发 1745 1925
Analysis 需求分析(包括学习新技术) 90 120
Design Spec 生成设计文档 30 40
Design Review 设计复审(和同事审核设计文档) 90 70
Coding Standard 代码规范(为目前的开发制定合适的规范) 20 20
Design 具体设计 40 50
Coding 具体编码 1080 1200
Code Review 代码复审 60 90
Test 测试(自我测试,修改代码,提交修改) 60 90
Reporting 报告 180 165
Test Report 测试报告 30 25
Size Measurement 计算工作量 5 5
Postmortem&Process Improvement Plan 事后总结并提出过程改进计划 60 50

  (6)小结:

  此次项目我们体验了结对编程,对于结对编程从一开始的没听过,到阅读过《构建之法》里面的结对编程的相关描述后,从理论上来说,我觉得结对编程是可以达到1+1>2的效果的,用为这个过程中,我们是统一体,一起学习,一起实践,通过分工合作,取长补短的方式让这个过程更加有意义,对于“我想不出这个点怎么做就只能死磕到底”的这种情况发生的几率有所下降,而是“一个想不出来,另一个换一个思路就可以想出了”的情况有所增加,这是一个共同促进的效果。从实践上来是,也确实是可以达到1+1>2的效果,但是也不是理论上的那么顺利,因为一个人有一个人的问题,两个人有两个人的问题,在开始的时候会在沟通或思想上有所分歧,但是经过磨合之后两个人的想法总会不谋而合,也就慢慢的好了,总的来说,通过这次实验,我从同伴身上、结对编程中学到了很多。遗憾的是,没能在有限的时间内想办法将所需实现的功能全部实现,下次还需要更加努力

原文地址:https://www.cnblogs.com/JZYWS/p/12571927.html