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的效果,但是也不是理論上的那么順利,因為一個人有一個人的問題,兩個人有兩個人的問題,在開始的時候會在溝通或思想上有所分歧,但是經過磨合之后兩個人的想法總會不謀而合,也就慢慢的好了,總的來說,通過這次實驗,我從同伴身上、結對編程中學到了很多。遺憾的是,沒能在有限的時間內想辦法將所需實現的功能全部實現,下次還需要更加努力


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM