201771030103-陈正丽 实验三 结对项目—《西北师范大学疫情防控信息系统》项目报告

项目 内容
课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/nwnu2020SE
这个作业要求链接 https://www.cnblogs.com/nwnu-daizh/p/12521474.html
我的课程学习目标 体验软件项目开发中的两人合作,练习结对编程(Pair programming);掌握Github协作开发程序的操作方法。
这个作业在哪些方面帮助我实现学习目标 更熟悉开发工具,团队协作的重要性
结对方学号-姓名 201771030106-葛佳诚
结对方本次博客作业链接 https://www.cnblogs.com/luor/p/12590222.html
本项目Github的仓库链接地址 https://github.com/201771030103/Shoolyiqing

实验目的与要求

(1)体验软件项目开发中的两人合作,练习结对编程(Pair programming)。

(2)掌握Github协作开发程序的操作方法。

实验内容与步骤

任务一:阅读《现代软件工程—构建之法》第3-4章内容,理解并掌握代码风格规范、代码设计规范、代码复审、结对编程概念;

  • 代码风格规范

    • 原则是:简明,易读,无二异性。

    • 主要注意事项包括 缩进、行宽、括号,断行与空白的{}行,分行,命名,下划线,大小写,注释。

  • 代码设计规范

    • 函数重要原则:只做一件事,并且要做好。

    • 函数最好有单一的出口,可以使用goto.

    • 错误处理涵盖参数处理和断言。

  • 代码复审

    • 定义:看代码是否在代码规范的框架内正确地解决了问题。

    • 代码复审的形式有三种:自我复审,同伴复审,团队复审。

    • 代码复审的目的在于:

      1. 发现代码的错误,比如:(1)编码错误,比如一些碰巧骗过了编译的错误 (2)不符合团队代码规范的地方

      2. 发现逻辑错误,程序可以编译通过,但是代码的逻辑是错的

      3. 发现算法错误,比如使用的算法不够优化,边界条件没有处理好等

      4. 发现潜在错误和回归性错误——当前的修改导致以前修复的缺陷又重新出现

      5. 发现可能需要改进的地方

      6. 教育(互相教育)开发人员,传授经验,让更多的成员熟悉项目各部分的代码,同时熟悉和应用领域相关的实际知识

  • 结对编程概念

    是指两个程序员在一个计算机上共同工作。一个人输入代码,而另一个人审查他输入的每一行代码。输入代码的人称作驾驶员,审查代码的人称作观察员(或导航员)。两个程序员经常互换角色。

任务2:两两自由结对,对结对方《实验二 软件工程个人项目》的项目成果进行评价,具体要求如下:

(1)对项目博文作业进行阅读并进行评论,评论要点包括:博文结构、博文内容、博文结构与PSP中“任务内容”列的关系、PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异化分析与原因探究,将以上评论内容发布到博客评论区。

(2)克隆结对方项目源码到本地机器,阅读并测试运行代码,参照《现代软件工程—构建之法》4.4.3节核查表复审同伴项目代码并记录。

克隆结对方项目及查看:

在本地查看克隆项目:

    1.概要部分

       代码已经测试通过,符合需求和规格说明,设计考虑周全,可读性强易维护。

    2.设计规范部分

        设计遵从项目中常用的模式,有部分硬编码和数字存在,代码没有依赖于平台,不会影响将来的移植,开发者新写的代码不能用已有的 Library/SDK/Framework中的功能实现,本项目中不存在类似的功能可以调用而不用重新实现,不存在没有用的 
     
      代码,绝不可清除。

    3.代码规范部分

       修改的部分符合代码标准和风格。

    4.具体代码部分

        做了相应的错误处理,对于调用的外部函数处理了异常,参数传递无错误,字符串的长度是字节的长度,是以0开始计数的,switch语句的default分支是以break结束的,不会出现死循环的情况,不可能存在资源泄露的问题,在图像用户界面方面可 
    
      以优化得更美观一点。

    5.效能

       代码效能很棒,最坏的情况也能执行出来,代码写得精简明了,图形界面的设计可优化得更完美,由于数据比较大,调用时可能会出现超时现象。

    6.可读性

       代码书写规范,可读性强。有足够的注释。

    7.可测试性

       代码测试时不需要更新或创建新的单元。     

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

结对方博客链接,点这里:https://www.cnblogs.com/luor/p/12590222.html

结对方Github项目仓库链接,(1)https://github.com/luorrr/SchoolInfoSystem (2)https://github.com/luorrr/UniversityInfoSystem

clone结对方代码:

fork并修改提交至github中:

任务3:采用两人结对编程方式,结合我校师生疫情每日上报系统使用体验,设计开发一款符合我校疫情防控工作需求的信息系统,使之具有以下功能:

需求分析:

2019年12月末,中国武汉发生新型冠状病毒(2019-nCoV) 感染的肺炎疫情,为遏制疫情蔓延,有效切断病毒传播途径,在中央政府指导下,各级政府部分采取了一系列防控措施: 2020年1 月23 日10时起对武汉“封城”,全国 31个省市也相继实施了严格的防控措施;全国各省市向武汉和湖北派遣医疗队参与救治工作;在全国范围内调配口罩、防护服、药品等急需的医疗资源支援武汉;指导和督促全国范围内拥有医疗物资生产资质的企业尽快恢复生产能力;定向拨付专项财政资金用于疾病防控;从其他省份调集物资保障武汉市民日常生活。
值得一提的是,中国互联网企业在此次疫情防控中发挥了社会治理方面的重要作用。以腾讯为例,围绕应对疫情管控需求开发了十一款产品。其中疫情在线问诊功能,对于减少发热病人之间的相互交叉感染具有重要的作用,患者在家通过互联网向在线医生问诊,减少了病毒传播或感染的风险;谣言粉碎对于公众采取理性态度看待疫情的发展具有重要意义。滴滴出行还在武汉专门组建车队,服务于医护人员的通勤,这在实施交通管制的武汉具有重要作用。此外,还有新型肺炎确诊患者同行程查询工具,用户只需要输入自己所乘坐交通工具的时间和班次,就可以确认是否与被确诊感染者同行,提前做好自我隔离和就诊工作。在疫情防控中,中国互联网企业不仅发展壮大,在承担社会责任方面也越来越成熟。
为有效配合防控机构有关疫情信息的采集、统计与排查,我校开发了教职工/学生疫情上报系统,该系统由教职工疫情每日上报、学生疫情每日上报、二级部门疫情每日汇总表、疫情防控填报统计四个子系统组成。实现对我校各类人员基本情况、所在区域及活动轨迹及健康状况的信息收集。

软件设计说明

(1)可采集全校各类师生员工疫情信息;

(2)各二级部门疫情防控工作负责人可查看本部门人员疫情汇总,并提供高级查询功能进行多属性组合查询和可视化统计功能;

(3)学校防控办指定负责人登录《西北师范大学疫情防控信息统计》子系统,可浏览所有人员填报汇总数据清单,利用【高级查询】可进行数据组合筛选,系统以图形化方式展示各学院已填报和未填报学生统计情况和关键疫情数据统计情况,可【导出】查询列表的EXCEL文件;

(4)人机交互界面要求GUI界面(WEB页面、APP页面都可);

(5)附加分功能:定时填报提醒

软件实现及核心功能代码展示

根据系统设计实际情况,设计数据库表有以下几张:
(1)学生信息登录表

(2)教师信息登录表

(3)管理人员信息登录表

代码结构如下:

关键代码:


public class ExcelUtil {
	
	// 不需要的字段
	//private static String passString = "count";

	/**
	 * 将list集合转成Excel文件
	 * 
	 * @param list 对象集合
	 * @param path 输出路径
	 * @return 返回文件路径
	 */
	public static String createExcel(List<? extends Object> list, String path) {
		String result = "";
		if (list.size() == 0 || list == null) {
			result = "没有对象信息";
		} else {
			Object o = list.get(0);
			Class<? extends Object> clazz = o.getClass();
			String className = clazz.getSimpleName();
			// 通过反射获取字段数组
			Field[] fields = clazz.getDeclaredFields();
			File folder = new File(path);
			if (!folder.exists()) {
				folder.mkdirs();
			}
			String fileName = new SimpleDateFormat("yyyyMMdd").format(new Date()).toString();
			String name = fileName.concat(".xls");
			WritableWorkbook book = null;
			File file = null;
			try {
				file = new File(path.concat(File.separator).concat(name));
				// 创建xls文件
				book = Workbook.createWorkbook(file);
				WritableSheet sheet = book.createSheet(className, 0);
				// 列
				int i = 0;
				// 行
				int j = 0;
				for (Field f : fields) {
					j = 0;
					// 这里把字段名称写入excel第一行中
					Label label = new Label(i, j, f.getName());
					sheet.addCell(label);
					j = 1;
					for (Object obj : list) {
						Object temp = getFieldValueByName(f.getName(), obj);
						String strTemp = "";
						if (temp != null) {
							strTemp = temp.toString();
						}
						// 把每个对象此字段的属性写入这一列excel中
						sheet.addCell(new Label(i, j, strTemp));
						j++;
					}
					i++;
				}
				book.write();
				result = file.getPath();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				result = "SystemException";
				e.printStackTrace();
			} finally {
				fileName = null;
				name = null;
				folder = null;
				file = null;
				if (book != null) {
					try {
						book.close();
					} catch (WriteException e) {
						// TODO Auto-generated catch block
						result = "WriteException";
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						result = "IOException";
						e.printStackTrace();
					}
				}
			}

		}
		// 输出文件路径
		return result;
	}

	/**
	 * ·根据属性名获取属性值
	 * 
	 * @param fieldName 属性名
	 * @param o
	 * @return 属性值
	 */
	private static Object getFieldValueByName(String fieldName, Object o) {
		try {
			String firstLetter = fieldName.substring(0, 1).toUpperCase();
			// 获取方法名
			String getter = "get" + firstLetter + fieldName.substring(1);
			// 获取方法对象
			Method method = o.getClass().getMethod(getter, new Class[] {});
			// 用invoke调用此对象的get字段方法
			Object value = method.invoke(o, new Object[] {});
			// 返回值
			return value;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

}

(1)登录界面,根据不同情况选择:

(2)学生信息录入:

(3)教师信息录入:

(4)录入成功会有提示:

(5)其他学院同学信息录入,录入成功会有提示:

(6)通过id可以查找学生/教师信息

查找显示结果:

(7)通过学号/工号+日期区间查找信息

查找显示结果:

(8)管理人员登录界面

管理人员登录后显示菜单:

(9)感染地区分布统计图

(10)感染人数统计图

(11)将查询结果导出:

导出成功:

结对过程:

PSP展示

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

小结感受:
通过这次实验,我能真实体验到两人合作真的能够带来1+1>2的效果,首先在编程方面,由于自己的编程能力有限,在很多功能方面自己一个人不能实现得了,而同伴在这方面能力比较强,因此能起到带领作用,其次,两人能通过网络工具随时交流,能规范代码书写,促进自己学习。经过这次实验,获益匪浅,在以后的学习中会再接再厉1!

原文地址:https://www.cnblogs.com/chenzhengli-/p/12556980.html