201771010134-杨其菊 实验三 结对项目—《西北师范大学疫情防控信息系统》项目报告

实验三 《西北师范大学疫情防控信息系统》项目报告

项目 内容
课程班级博客链接 https://www.cnblogs.com/nwnu-daizh/
作业要求链接 https://www.cnblogs.com/nwnu-daizh/p/12521474.html
我的课程学习目标 (1)学习软件工程基础概念和理论;(2)学习个人在团队中如何发挥作用;(3)团队如何更好协作;(4)熟悉项目开发的流程
这个作业在哪些方面帮助我实现课程目标 (1)体验软件项目开发中的两人合作,练习结对编程。(2)掌握Github协作开发程序的操作方法。
结对方学号-姓名 201771010132-徐思
结对方本次博客作业链接 https://www.cnblogs.com/sisi-713/p/12566861.html
本项目仓库Github链接 https://github.com/Tanya11010

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

  • 代码风格设计:主要是文字上的规定,代码风格的原则是:简明,易读,无二义性。
    • 如缩进格式为4个空格,阅读体验正好;
    • 行宽:行宽限制为100字符;
    • 括号:用括号清楚地表示逻辑优先级;
    • 分行:不降多条语句放在一行上;
    • 命名:设定通用准则,使程序员阅读代码时能一眼看出变量的类型等,方便阅读。
  • 代码设计规范:不光是程序书写,而且牵涉到程序设计、模块之间的关系、设计模式等方方面面的通用原则。
    • 函数:
    • 错误处理:
  • 代码复审:看代码是否在代码规范的框架内正确地解决了问题。
    • 形式:自我复审、同伴复审和团队复审三种形式,其中最常用的就是同伴复审。
    • 目的:1)找出代码的错误,比如编码错误和不符合团队代码规范的部分。
      2)发现逻辑错误
      3)发现算法错误
      4)发现可能需要改进的地方。
      5)传授经验,让更多的成员熟悉项目各部分的代码。
    • 结果:对于复审者提出的问题,开发者都必须详细解释。复审后,开发者应该把复审过程中的记录整理出来。
  • 结对编程:
    • 开发层次:结对编程能提供更好的设计质量和代码质量,两个人合作解决问题的能力更强,两人合作,也有互相激励的作用。
      -对于开发人员自身来说,结对工作能带来更多的信心,高质量的产出能增强满足感。
    • 企业管理层次:结对能更有效地交流,相互学习和传递经验。

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

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

同伴对我的项目成果评价:

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

  • 1.概要部分
    1)代码符合需求和规格说明么?
    答:基本符合。

2)代码设计是否考虑周全?
答:考虑较为周全。

3)代码可读性如何?
答:可读性高。

4)代码容易维护么?
答:较易维护。

5)代码的每一行都执行并检查过了吗?
答:已检查。

  • 2.设计规范部分
    1)设计是否遵从已知的设计模式或项目中常用的模式?
    答:

    2)有没有硬编码或字符串/数字等存在?
    答:没有。

    3)代码有没有依赖于某一平台, 是否会影响将来的移植(如Win32到Win64) ?
    答:没有。

    4)开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现?
    答:

    5)有没有无用的代码可以清除?
    答:

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

  • 4.具体代码部分
    1)有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常?
    答:有对错误进行处理,对于调用的外部函数,检查了返回值,处理了异常。

    2)参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数?
    答:基本没有错误,

    3)边界条件是如何处理的?switch语句的default分支是如何处理的?循环有没有可能出现死循环?
    答:

    4)有没有使用断言( Assert)来保证我们认为不变的条件真的得到满足?
    答:

    5)对资源的利用,是在哪里申请,在哪里释放的?有无可能存在资源泄漏(内存、文件、各种GUI资源、数据库访问的连接,等等) ?有没有优化的空间?
    答:

    6)数据结构中有没有用不到的元素?
    答:

  • 5.效能
    1)代码的效能( Performance )如何?最坏的情况是怎样的?
    答:
    2)代码中,特别是循环中是否有明显可优化的部分(C++中反复创建类,C#中string的操作是否能用StringBuilder来优化) ?

    3)对于系统和网络的调用是否会超时?如何处理?

  • 6.可读性
    1)代码可读性如何?有没有足够的注释?
    答:可读性较高,注释较详细

  • 7.可测试性
    1)代码是否需要更新或创建新的单元测试?
    答:不需要。

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

Clone到本地仓库:

任务3:采用两人结对编程方式,结合我校师生疫情每日上报系统使用体验,设计开发一款符合我校疫情防控工作需求的信息系统,使之具有以下功能:
(1)可采集全校各类师生员工疫情信息;
(2)各二级部门疫情防控工作负责人可查看本部门人员疫情汇总,并提供高级查询功能进行多属性组合查询和可视化统计功能;
(3)学校防控办指定负责人登录《西北师范大学疫情防控信息统计》子系统,可浏览所有人员填报汇总数据清单,利用【高级查询】可进行数据组合筛选,系统以图形化方式展示各学院已填报和未填报学生统计情况和关键疫情数据统计情况,可【导出】查询列表的EXCEL文件;
(4)人机交互界面要求GUI界面(WEB页面、APP页面都可);
(5)附加分功能:定时填报提醒
1.需求分析
*2.功能设计:
1)可以采集全校师生疫情信息;
2)学生/教职工可填报信息;
3)学生可修改登录密码;
4)二级部门负责人可以增加、删除,修改学生填报的信息;
5)二级部门负责人查询某人在某一天的疫情情况;
6)学校负责人可以浏览疫情汇总信息清单;
7)学校负责人可以查询已填报和未填报学生;
8)学校负责人可以查询每月疑似例/确诊例新增人数等关键数据的统计情况及用柱形图显示的结果;
9)附加功能:定时人们提醒填报;
3.设计实现:软件包括哪些类,这些类分别负责什么功能,他们之间的关系怎样?类内有哪些重要的方法,关键的方法是否需要画出流程图?
1)Util 数据库连接
JDBC.java 封装JDBC工具类,连接、释放资源
StringUtil.java
2)com.tjl.view 视图包
LogOnFrame.java 登录类
addInterFrame.java
studentFrame.java
teacherFrame.java
recordFrame.java
adminFrame.java
secadminFrame.java
recordInter.java
InterFrame4.java

3)com.tjl.test 测试类包
JDBCUtilsTest.java 测试mysql进行语句类
ViewTest.java 测试各种视图的类
4)model用户类包
student.java 封装学生类
teacher.java 封装教师类
record.java 封装信息记录类
5)chart 柱形图包
Chart.java 封装柱形图类
5)创建数据库(xsyq),数据表(student,teacher,record,admin,secadmin)
6)dao 对数据库访问的类实现
studentDao.java
teacherDao.java
adminDao.java
secadminDao.java
recordDao.java
7)Main 主程序
Main.Java 程序入口
4.核心代码展示

package com.tjl.jdbc;

import java.sql.DriverManager;

import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Connection;
/**
 * jdbc连接数据库
 * @author by yqj;
 */
package view;

import java.awt.EventQueue;
import java.sql.Connection;
import java.sql.ResultSet;

import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JTable;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.table.DefaultTableModel;

import dao.RecordDao;
import model.Record;
import util.JDBC;

import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class readrecordInter extends JInternalFrame {
    private JTable readtable;
    private JTextField datetext;
    private JDBC jdbc=new JDBC();
    private JComboBox comboBox;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    readrecordInter frame = new readrecordInter();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public readrecordInter() {
        setTitle("浏览记录");
        setMaximizable(true);
        setIconifiable(true);
        setClosable(true);
        setBounds(100, 100, 763, 528);
        
        JScrollPane scrollPane = new JScrollPane();
        
        JPanel panel = new JPanel();
        GroupLayout groupLayout = new GroupLayout(getContentPane());
        groupLayout.setHorizontalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(groupLayout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
                        .addComponent(panel, GroupLayout.DEFAULT_SIZE, 717, Short.MAX_VALUE)
                        .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 717, Short.MAX_VALUE))
                    .addContainerGap())
        );
        groupLayout.setVerticalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(groupLayout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(panel, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE)
                    .addGap(71)
                    .addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 174, GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(166, Short.MAX_VALUE))
        );
        
        JLabel lblNewLabel = new JLabel("学院:");
        
        JLabel lblNewLabel_1 = new JLabel("日期:");
        
        datetext = new JTextField();
        datetext.setColumns(10);
        
        JButton read = new JButton("浏览");

        
       comboBox = new JComboBox();
       comboBox.setModel(new DefaultComboBoxModel(new String[] {"计算机学院", "历史学院", "数统院", "外国语学院"}));
        GroupLayout gl_panel = new GroupLayout(panel);
        gl_panel.setHorizontalGroup(
            gl_panel.createParallelGroup(Alignment.LEADING)
                .addGroup(gl_panel.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(lblNewLabel_1)
                    .addPreferredGap(ComponentPlacement.UNRELATED)
                    .addComponent(datetext, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addGap(46)
                    .addComponent(lblNewLabel)
                    .addGap(18)
                    .addComponent(comboBox, GroupLayout.PREFERRED_SIZE, 157, GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(ComponentPlacement.RELATED, 157, Short.MAX_VALUE)
                    .addComponent(read)
                    .addGap(36))
        );
        gl_panel.setVerticalGroup(
            gl_panel.createParallelGroup(Alignment.LEADING)
                .addGroup(gl_panel.createSequentialGroup()
                    .addContainerGap(17, Short.MAX_VALUE)
                    .addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
                        .addComponent(lblNewLabel_1)
                        .addComponent(datetext, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(lblNewLabel)
                        .addComponent(read)
                        .addComponent(comboBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addContainerGap())
        );
        panel.setLayout(gl_panel);
        
        readtable = new JTable();
        scrollPane.setViewportView(readtable);
        readtable.setModel(new DefaultTableModel(
            new Object[][] {
            },
            new String[] {
                "\u8D26\u53F7", "\u59D3\u540D", "\u6027\u522B", "\u6E56\u5317\u7C4D", "\u5B66\u9662", "\u7535\u8BDD", "\u63A5\u89E6\u75AB\u533A", "\u7591\u4F3C", "\u786E\u8BCA", "\u5730\u5740", "\u65E5\u671F", "\u5907\u6CE8"
            }
        ) {
            boolean[] columnEditables = new boolean[] {
                false, true, true, true, true, true, true, true, true, true, false, true
            };
            public boolean isCellEditable(int row, int column) {
                return columnEditables[column];
            }
        });
        getContentPane().setLayout(groupLayout);
        this.fillRead("read");

    }
   

    /**
     * 初始化下拉列表
     * @param type
     */
    private void fillRead(String type){
        Connection con=null;
        Record record=null;
        try{
            con=jdbc.getCon();
            ResultSet rs=RecordDao.list(con, new Record());
            while(rs.next()){
                record.setDate(rs.getString("date"));
                
                if("read".equals(type)){
                    this.comboBox.addItem(record);
                }
                else if("modify".equals(type)){
                    this.comboBox.addItem(record);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try {
                jdbc.closeCon(con);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

5.程序运行

6.结对过程讨论

7.PSP

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

8.小结感受:结对编程真的能带来1+1>2的效果,两个人可以解决更多的问题,提出更多的想法。

猜你喜欢

转载自www.cnblogs.com/yqj-yf-111/p/12588932.html