项目 | 内容 |
---|---|
课程班级博客链接 | https://edu.cnblogs.com/campus/xbsf/nwnu2020SE |
作业要求链接 | https://www.cnblogs.com/nwnu-daizh/p/12521474.html |
我的学习目标 | 掌握软件项目个人开发流程;掌握Github发布软件项目的操作方法; |
这个作业在哪些方面帮助我实现学习目标 | 掌握了个人软件项目开发的大致流程;熟悉了GitHub托管发布项目的基本流程。 |
结对方学号-姓名 | 201571030115-李雪芬 |
结对方本次博客作业链接 | https://www.cnblogs.com/lixuefen/p/12586643.html |
项目Github的仓库链接地址 | https://github.com/syy2020/student |
任务二 两两自由结对,对结对方《实验二 软件工程个人项目》的项目成果进行评价,具体要求如下:
(1)对项目博文作业进行阅读并进行评论,评论要点包括:博文结构、博文内容、博文结构与PSP中“任务内容”列的关系、PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异化分析与原 因探究,将以上评论内容发布到博客评论区。
(2)克隆结对方项目源码到本地机器,阅读并测试运行代码,参照《现代软件工程—构建之法》4.4.3节核查表复审同伴项目代码并记录。
(3)依据复审结果尝试利用github的Fork、Clone、Push、Pull request、Merge pull request等操作对同伴个人项目仓库的源码进行合作修改。
结对方博客链接https://www.cnblogs.com/lixuefen/
结对方Github项目仓库链接https://github.com/k20465/student
代码核查表
概要部分
代码符合需求和规格说明吗? 答:代码符合需求和规范说明。
代码设计是否考虑全面? 答:代码设计不够全面
代码可读性怎样? 答:代码的可读性较差
代码容易维护吗? 答:容易维护。
代码的每一行都执行并检查过了吗? 答:是的,都检查过了。
设计规范部分
设计是否遵从已知的设计模式或项目中常用的模式? 答:是的,遵从
有没有硬编码或字符串/数字等存在? 答:没有
代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到Win64) 答:没有依赖,没有影响
开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现? 答:可以实现,不存在
有没有无用的代码可以清除?(很多人想保留尽可能多的代码,因为以后可能会用上,这样导致程序文件中有很多注释掉的代码,这些代码都可以删除,因为源代码控制已经保存了原来的老代码。) 答:存在无用代码
代码规范部分
修改的部分符合代码标准和风格么(详细条文略)? 答:符合代码标准
具体代码部分
有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常? 答:有对错误进行处理,检查了返回值和异常。
循环有没有可能出现死循环? 答:不会出现死循环
有没有使用断言(Assert)来保证我们认为不变的条件真的满足? 答:没有使用
数据结构中是否有无用的元素? 答:有部分存在无用元素,已做处理。
效能
代码的效能(Performance)如何?最坏的情况是怎样的?答:效能一般,最差情况是运行速度慢
代码中,特别是循环中是否有明显可优化的部分(C++中反复创建类,C#中 string 的操作是否能用StringBuilder 来优化)?答:有
可读性
代码可读性如何?有没有足够的注释? 答:代码的可读性一般,有部分注释。
可测试性
代码是否需要更新或创建新的单元测试?还可以有针对特定领域开发(如数据库、网页、多线程等)的核查表 答:需要。
结对方项目仓库中的Fork、Clone、Push、Pull request、Merge pull request日志数据
任务三:采用两人结对编程方式,结合我校师生疫情每日上报系统使用体验,设计开发一款符合我校疫情防控工作需求的信息系统
1、需求分析陈述
2019年12月末,中国武汉发生新型冠状病毒(2019-nCoV) 感染的肺炎疫情,为遏制疫情蔓延,有效切断病毒传播途径,在中央政府指导下,各级政府部分采取了一系列防控措施: 2020年1 月23 日10时起对武汉“封城”,全国 31个省市也相继实施了严格的防控措施;全国各省市向武汉和湖北派遣医疗队参与救治工作;在全国范围内调配口罩、防护服、药品等急需的医疗资源支援武汉;指导和督促全国范围内拥有医疗物资生产资质的企业尽快恢复生产能力;定向拨付专项财政资金用于疾病防控;从其他省份调集物资保障武汉市民日常生活。
值得一提的是,中国互联网企业在此次疫情防控中发挥了社会治理方面的重要作用。以腾讯为例,围绕应对疫情管控需求开发了十一款产品。其中疫情在线问诊功能,对于减少发热病人之间的相互交叉感染具有重要的作用,患者在家通过互联网向在线医生问诊,减少了病毒传播或感染的风险;谣言粉碎对于公众采取理性态度看待疫情的发展具有重要意义。滴滴出行还在武汉专门组建车队,服务于医护人员的通勤,这在实施交通管制的武汉具有重要作用。此外,还有新型肺炎确诊患者同行程查询工具,用户只需要输入自己所乘坐交通工具的时间和班次,就可以确认是否与被确诊感染者同行,提前做好自我隔离和就诊工作。在疫情防控中,中国互联网企业不仅发展壮大,在承担社会责任方面也越来越成熟。
为有效配合防控机构有关疫情信息的采集、统计与排查,我校开发了教职工/学生疫情上报系统,该系统由教职工疫情每日上报、学生疫情每日上报、二级部门疫情每日汇总表、疫情防控填报统计四个子系统组成。实现对我校各类人员基本情况、所在区域及活动轨迹及健康状况的信息收集。在此基础上提供了高级查询,相对的可视化功能,定时功能以及导出到excel表中的功能。
2、软件设计说明
(1)可以对老师/学生的信息进行采集
(2)二级部门可对所属人员信息进行查看,并支持高级查询,同时还有防疫关键信息的柱状图显示功能
(3)学校防控办指定负责人登录系统,浏览所有人员信息,并且利用高级查询可进行数据组合筛选。在数据可视化的设计上,一方面以扇形图的方式展示各学院已填报和未填报学生统计情况,另一方面以柱状图的形式显示关键疫情数据统计情况,同时也可以根据搜索结果导出查询数据到EXCEL文件
(4)人机交互界面要求GUI界面(WEB页面、APP页面都可);
(5)附加分功能:定时填报提醒:
3、主要代码
import java.awt.event.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.BorderLayout;
class esInfo extends JPanel implements ActionListener,Listener {
JPanel panel = new JPanel();
JButton btnAdd = new JButton("增加");
JButton btnDelete = new JButton("删除");
JButton btnAlter = new JButton("修改");
JButton btnSearch = new JButton("查询");
JButton btnDisplay = new JButton("刷新");
JTable table;
JScrollPane scroll;
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
Object[][] columnValues;
String [] columnNames;
DefaultTableModel tableModel;
esInfo() {// 构造方法
setLayout(new BorderLayout(0, 0));
add(panel, BorderLayout.NORTH);
panel.add(btnAdd);
panel.add(btnDelete);
panel.add(btnAlter);
panel.add(btnSearch);
panel.add(btnDisplay);
btnAdd.addActionListener(this);
btnDelete.addActionListener(this);
btnAlter.addActionListener(this);
btnSearch.addActionListener(this);
btnDisplay.addActionListener(this);
columnNames=new String []{"学号","姓名","填报时间","所在地","当前健康状况"};
getAllCourses();
tableModel=new DefaultTableModel(columnValues,columnNames);
table=new JTable(tableModel);
scroll=new JScrollPane(table);
add(scroll);
}
//获取课程列表
public void getAllCourses(){
int count=0,index=0;
connDB();// 连接数据库
try{
rs=stmt.executeQuery("select count(*) from su");
rs.next();
count=rs.getInt(1);
}catch(SQLException e){
e.printStackTrace();
}
columnValues=new Object[count][5];
try{
rs=stmt.executeQuery("select * from su order by 学号");
while(rs.next()){
columnValues[index][0]=rs.getString("学号");
columnValues[index][1]=rs.getString("姓名");
columnValues[index][2]=rs.getInt("填报时间");
columnValues[index][3]=rs.getString("所在地");
columnValues[index][4]=rs.getString("当前健康状况");
index++;
}
}catch(SQLException e){
e.printStackTrace();
}
closeDB();
}
//刷新课程列表
public void refresh(){
getAllCourses();
tableModel.setDataVector(columnValues, columnNames);
tableModel.fireTableDataChanged();
}
public void connDB() { // 连接数据库
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
con = DriverManager.getConnection(
"jdbc:sqlserver://localhost:1433; DatabaseName=ers",
"SA", "111111");
stmt = con.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void closeDB() // 关闭连接
{
try {
stmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void update() {
int row = -1;
row = table.getSelectedRow();
connDB();
if (row == -1) {
JOptionPane.showMessageDialog(null, "请选择要修改的记录!");
} else {
esAdd cadd=new esAdd(this);
cadd.setTitle("修改");
cadd.t学号.setText(columnValues[row][0].toString());
cadd.t姓名.setText(columnValues[row][1].toString());
cadd.t填报时间.setText(columnValues[row][2].toString());
cadd.t所在地.setText(columnValues[row][3].toString());
cadd.t当前健康状况.setText(columnValues[row][4].toString());
cadd.t学号.setEnabled(false);
}
closeDB();
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "增加") {
new esAdd(this);
}
if (e.getActionCommand() == "删除") {
delete();
}
if (e.getActionCommand() == "修改") {
update();
}
if (e.getActionCommand() == "查询") {
new InputNumber("学号",this);
}
if (e.getActionCommand() == "刷新") {
refresh();
}
}
@Override
public void refreshUI() {
refresh();
}
@Override
public void getMessage(String message) {
connDB();
columnValues = new Object[1][5];
try {
rs = stmt.executeQuery("select * from su where 学号='" +message+ "'");
rs.next();
columnValues[0][0] = rs.getString("学号");
columnValues[0][1] = rs.getString("姓名");
columnValues[0][2] = rs.getInt("填报时间");
columnValues[0][3] = rs.getString("所在地");
columnValues[0][4] = rs.getString("当前健康状况");
} catch (SQLException e) {
e.printStackTrace();
}
if (columnValues[0][1] == null) {
JOptionPane.showMessageDialog(null, "学号不存在!");
refresh();
} else {
tableModel.setDataVector(columnValues, columnNames);
tableModel.fireTableDataChanged();
}
closeDB();
}
}
4、运行测试
数据库设计
登录界面
学生修改信息及疫情填报
学校负责人
学院负责人
5、结对完成项目过程
6、讨论截图
psp
PSP | 任务内容 | 计划共需的时间(min) | 实际所需的时间(min) |
---|---|---|---|
planning | 计划 | 35 | 25 |
Estimate | 估计这个任务所需时间,并作规划 | 35 | 45 |
Development | 开发 | 650 | 900 |
Analysis | 需求分析 | 300 | 240 |
Design Spec | 生成设计文档 | 20 | 30 |
Design Review | 设计复审(和同事审核设计文档) | 20 | 30 |
Coding Standar | 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
Design | 具体设计 | 220 | 180 |
Coding | 具体编码500 | 800 | |
Code Review | 代码复审 | 150 | 180 |
Test | 测试 | 50 | 200 |
Reporting | 报告 | 50 | 50 |
Test Report | 测试报告 | 35 | 45 |
Size Measurement | 计算工作量 | 20 | 10 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划10 | 20 |
小结
通过这次结对合作后,虽然我们的编程能力都比较薄弱,但是在结对编程的过程中,通过两个人互相交流解决问题,每个人在编程中做的工作相对减少一些,相互交换想法和经验,编程过程能够及时发现存在的错误并改正,合作能够达到1+1>2的效果。