zoukankan      html  css  js  c++  java
  • 201771030114-马强 实验三 结对项目—《西北师范大学疫情防控信息系统》项目报告

    项目 内容
    班级博客链接 https://edu.cnblogs.com/campus/xbsf/nwnu2020SE
    作业要求链接 https://www.cnblogs.com/nwnu-daizh/p/12521474.html
    学习目标 掌握软件项目个人开发流程及Github发布软件项目的操作方法。
    本作业在哪方面帮我完成学习目标 根据实际需求独立开发项目
    对方姓名学号 201771030113-李志龙
    结对方博客链接 https://www.cnblogs.com/zhilong12/p/12573950.html
    github仓库地址 https://github.com/AlexCrizs/yiqing2.0

    实验步骤和内容

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

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

    (1)对项目博文作业进行阅读并进行评论,将评论内容发布到博客评论区。




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



    fork对方项目到我的仓库,并进行pull等操作

    概要部分

    • 代码能符合需求和规格说明么?
      答:符合需求与规格
    • 代码设计是否有周全考虑?
      答:考虑地不是很全面,还是存在问题,功能还需完善
    • 代码可读性如何?
      答:符合规范,可读性高,解释的很清楚,容易理解
    • 代码容易维护么?
      答:还好,比较容易维护
    • 代码的每一行都执行并检查过了吗?
      答:是的

    设计规范部分

    • 设计是否遵从已知的设计模式或项目中常用的模式?
      答:是的
    • 有没有硬编码或字符串/数字等存在?
      答:没有
    • 代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到Win64)
      答:不会影响
    • 开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现?
      答:可以;存在
    • 有没有无用的代码可以清除?
      答:已经整理完成

    代码规范部分

    • 修改的部分符合代码标准和风格么(详细条文略)?
      答:符合

    具体代码部分

    • 有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常?
      答:有对错误进行处理,并对调用的外部函数,检查了返回值且处理了异常
    • 参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数?
      答:基本无错误,字符串的长度是字节的长度,以0开始计数。
    • 边界条件是如何处理的?Switch语句的Default是如何处理的?循环有没有可能出现死循环?
      答:不断测试改进,不会出现死循环
    • 有没有使用断言(Assert)来保证我们认为不变的条件真的满足?
      答:目前没有
    • 对资源的利用,是在哪里申请,在哪里释放的?有没有可能导致资源泄露(内存、文件、各种GUI资源、数据库访问的连接,等等)?有没有可能优化?
      答:jdbc访问时申请,访问结束后断开,不会导致资源泄漏,有可能优化
    • 数据结构中是否有无用的元素?
      答:目前没有找到

    效能

    • 代码的效能(Performance)如何?最坏的情况是怎样的?
      答:效能一般,最差情况是访问速度很慢
    • 代码中,特别是循环中是否有明显可优化的部分(C++中反复创建类,C#中 string 的操作是否能用StringBuilder 来优化)?
      答:可能有,不过能力不够,只能做到这
    • 对于系统和网络调用是否会超时?如何处理?
      答:没有出现过超时现象

    可读性

    • 代码可读性如何?有没有足够的注释?
      答:代码可读性一般,有注释

    可测试性

    • 代码是否需要更新或创建新的单元测试?还可以有针对特定领域开发(如数据库、网页、多线程等)的核查表
      答:不需要
    • 依据复审结果尝试利用github的Fork、Clone、Push、Pull request、Merge pull request等操作对同伴个人项目仓库的源码进行合作修改。
      fork

      pullrequest等操作


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

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


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


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


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

    1.需求分析

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

    2.功能设计

    基本功能

    • 系统可采集学生疫情有效信息;
    • 学生在前端提交信息到管理员端;
    • 各学院指定负责人登录系统,可查看学生填报的所有汇总数据
    • 负责人可根据学生的姓名,学院,查找相关信息
    • 负责人通过【导出】可获取疫情数据的EXCEL文件
    • 负责人可通过图形化方式查看各学院的疫情数据统计情况

    3.设计实现

    (1)数据库建立了四个表分别存储教师、学生、二级部和防控办的信息

    (2)eclipse工程目录及类的设计与分析

    包含了控制层,数据层,服务层,还写了学生类、老师类等
    设计接口时,给每一个接口按一定比例设计分配方法,减少代码冗余。且高层模块不依赖低层模块。
    在登录界面中调用类Dao中的方法判断是否登录成功,如果登录成功就会根据用户类型转到相关界面;
    数据可视化时将会调用jfree chart包中的方法中的方法来显示柱状图

    流程图如下

    (3)登陆页面









    (4)登记填报



    (5)校防控办查看



    (6)二级部门查询


    (7)柱状图查看


    (8)Excel导出





    (9)附加提醒功能没有实现

    (10)主要代码

    import java.io.IOException;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.tagext.TagSupport;
    
    import com.MQLZL.comm.utils.Page;
    
    /**
     * 显示格式 上一页 1 2 3 4 5 下一页
     */
    public class NavigationTag extends TagSupport {
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    
    	/**
    	 * request 中用于保存Page<E> 对象的变量名,默认为“page”
    	 */
    	private String bean = "page";
    
    	/**
    	 * 分页跳转的url地址,此属性必须
    	 */
    	private String url = null;
    
    	/**
    	 * 显示页码数量
    	 */
    	private int number = 5;
    
    	@Override
    	public int doStartTag() throws JspException {
    		JspWriter writer = pageContext.getOut();
    		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
    		Page page = (Page) request.getAttribute(bean);
    		if (page == null)
    			return SKIP_BODY;
    		url = resolveUrl(url, pageContext);
    		try {
    			// 计算总页数
    			int pageCount = page.getTotal() / page.getSize();
    			if (page.getTotal() % page.getSize() > 0) {
    				pageCount++;
    			}
    			writer.print("<nav><ul class="pagination">");
    			// 显示“上一页”按钮
    			if (page.getPage() > 1) {
    				String preUrl = append(url, "page", page.getPage() - 1);
    				preUrl = append(preUrl, "rows", page.getSize());
    				writer.print("<li><a href="" + preUrl + "">上一页</a></li>");
    			} else {
    				writer.print("<li class="disabled"><a href="#">上一页</a></li>");
    			}
    			// 显示当前页码的前2页码和后两页码
    			// 若1 则 1 2 3 4 5, 若2 则 1 2 3 4 5, 若3 则1 2 3 4 5,
    			// 若4 则 2 3 4 5 6 ,若10 则 8 9 10 11 12
    			int indexPage = (page.getPage() - 2 > 0) ? page.getPage() - 2 : 1;
    			for (int i = 1; i <= number && indexPage <= pageCount; indexPage++, i++) {
    				if (indexPage == page.getPage()) {
    					writer.print("<li class="active"><a href="#">" + indexPage
    							+ "<span class="sr-only">(current)</span></a></li>");
    					continue;
    				}
    				String pageUrl = append(url, "page", indexPage);
    				pageUrl = append(pageUrl, "rows", page.getSize());
    				writer.print("<li><a href="" + pageUrl + "">" + indexPage + "</a></li>");
    			}
    			// 显示“下一页”按钮
    			if (page.getPage() < pageCount) {
    				String nextUrl = append(url, "page", page.getPage() + 1);
    				nextUrl = append(nextUrl, "rows", page.getSize());
    				writer.print("<li><a href="" + nextUrl + "">下一页</a></li>");
    			} else {
    				writer.print("<li class="disabled"><a href="#">下一页</a></li>");
    			}
    			writer.print("</nav>");
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return SKIP_BODY;
    	}
    
    	private String append(String url, String key, int value) {
    		return append(url, key, String.valueOf(value));
    	}
    
    	/**
    	 * 为url 参加参数对儿
    	 */
    	private String append(String url, String key, String value) {
    		if (url == null || url.trim().length() == 0) {
    			return "";
    		}
    		if (url.indexOf("?") == -1) {
    			url = url + "?" + key + "=" + value;
    		} else {
    			if (url.endsWith("?")) {
    				url = url + key + "=" + value;
    			} else {
    				url = url + "&amp;" + key + "=" + value;
    			}
    		}
    		return url;
    	}
    
    	/**
    	 * 为url 添加翻页请求参数
    	 */
    	private String resolveUrl(String url, javax.servlet.jsp.PageContext pageContext) throws JspException {
    		Map params = pageContext.getRequest().getParameterMap();
    		for (Object key : params.keySet()) {
    			if ("page".equals(key) || "rows".equals(key))
    				continue;
    			Object value = params.get(key);
    			if (value == null)
    				continue;
    			if (value.getClass().isArray()) {
    				url = append(url, key.toString(), ((String[]) value)[0]);
    			} else if (value instanceof String) {
    				url = append(url, key.toString(), value.toString());
    			}
    		}
    		return url;
    	}
    
    	public String getBean() {
    		return bean;
    	}
    
    	public void setBean(String bean) {
    		this.bean = bean;
    	}
    
    	public String getUrl() {
    		return url;
    	}
    
    	public void setUrl(String url) {
    		this.url = url;
    	}
    
    	public void setNumber(int number) {
    		this.number = number;
    	}
    }
    

    4.两人合作的截图



    描述结对过程,微信截图



    PSP 任务内容 计划共需的时间(min) 实际所需的时间(min)
    planning 计划 30 20
    Estimate 估计这个任务所需时间,并作规划 30 40
    Development 开发 600 800
    Analysis 需求分析 300 240
    Design Spec 生成设计文档 30 30
    Design Review 设计复审(和同事审核设计文档) 60 90
    Coding Standard 代码规范 (为目前的开发制定合适的规范) 20 20
    Design 具体设计 200 150
    Coding 具体编码 400 450
    Code Review 代码复审 150 200
    Test 测试 50 100
    Reporting 报告 50 65
    Test Report 测试报告 30 35
    Size Measurement 计算工作量 20 20
    Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 10 15

    总结

    这次实验比上一次有很大的进步,预计时间和实际时间的差距缩小了很多,这次项目在前期计划上更加的合理,实验功能完成的比上一次要好,但遗憾的是,提醒功能没有完成,后续开发中会持续更新
    这次最重要的是两个人结对编程,真正意义上的实现了1+1>2的效果,实验的效率提高了很多,互相之间可以取长补短,大大缩短了开发时间。希望以后可以共同努力,做出更好的作品。r

  • 相关阅读:
    大数据全栈式开发语言 – Python
    史上最全的“大数据”学习资源(上)(山东数漫江湖)
    Hadoop大数据生态系统及常用组件(山东数漫江湖)
    Vue前端开发规范(山东数漫江湖)
    BTA 常问的 Java基础40道常见面试题及详细答案(山东数漫江湖))
    Spring 框架的设计理念与设计模式分析(山东数漫江湖)
    SSM三大框架整合详细总结(Spring+SpringMVC+MyBatis)(山东数漫江湖)
    深入理解Spring MVC(山东数漫江湖)
    Oracle中varchar,varchar2,nvarchar,nvarchar2的区别及其它数据类型描述
    再见,霍金
  • 原文地址:https://www.cnblogs.com/AlexCrizs/p/12587824.html
Copyright © 2011-2022 走看看