高級軟件工程第三次作業
0 小組成員
韓華頌 2016282110142
吳政楠 2017282110286
1 項目Github地址
https://coding.net/u/songofjoy/p/softwareProject/git
2 預估耗時
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 10 | 10 |
· Estimate | · 估計這個任務需要多少時間 | 10 | 10 |
Development | 開發 | 1140 | 1360 |
· Analysis | · 需求分析 (包括學習新技術) | 60 | 80 |
· Design Spec | · 生成設計文檔 | 60 | 80 |
· Design Review | · 設計復審 (和同事審核設計文檔) | 30 | 40 |
· Coding Standard | · 代碼規範 (為目前的開發制定合適的規範) | 30 | 40 |
· Design | · 具體設計 | 60 | 70 |
· Coding | · 具體編碼 | 600 | 700 |
· Code Review | · 代碼復審 | 180 | 200 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 120 | 150 |
Reporting | 報告 | 180 | 150 |
· Test Report | · 測試報告 | 150 | 120 |
· Size Measurement | · 計算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事後總結, 並提出過程改進計劃 | 20 | 20 |
合計 | 1330 | 1520 |
3 解題思路
3.1 前期準備
在上一次作業中,我們已經生成了一個簡單的算式生成器,但是其中還有括號的功能沒有實現。基礎代碼選取了我們兩人中性能較高的一個,本次項目不僅要實現GUI,還要在之前的基礎上實現括號。
3.2 後端
以上次的作業為基礎,繼續對上次的作業進行更一步的開發——添加括號。
3.3 前端
通過利用windowbuilder插件,可以將GUI展現給用戶。
3.4 分歧解決
在最開始設計時,我們對GUI的呈現方式產生了分歧:
1、以計算器的形式展現
2、以網頁的方式展現
後來經過討論,從時間角度和熟練程度考慮選取了以計算器的方式展示。
4 設計實現過程
4.1 獲取題目
textField.setText(Equation.createEquation().toString());
其中Equation是一個隨機生成算式的函數
4.2 保存統計數據
public static void saveScore(Score score) throws IOException, ParseException { FileWriter writer = new FileWriter(FILENAME); writer.write(score.getRightAmount() + SPLITSTRING); writer.write(score.getWrongAmount() + SPLITSTRING); writer.write(score.getRadioAmount() + SPLITSTRING); writer.close(); }
4.3 讀取統計數據
public static Score readScore() throws IOException, ParseException { Score score=new Score(); BufferedReader reader = new BufferedReader(new FileReader(FILENAME)); String line = reader.readLine(); String []infos=line.split(SPLITSTRING); score.setRightAmount(Integer.valueOf(infos[0])); score.setWrongAmount(Integer.valueOf(infos[1])); score.setRadioAmount(Double.valueOf(infos[2])); return score; }
4.4 計時器
對計時器進行的初始化設置
static int timer=0; static long starttimer=0; DecimalFormat df= new DecimalFormat("######0.0");
4.5 多語言支持
static final String EN="resource_english"; static final String CH="resource_zh_CN_1"; static final String HARD="resource_hard";
5 代碼說明
5.1顯示當前數據
將當前的正確題目數、錯誤題目數以及正確率記錄在dat文件中,每次答題完成後點擊下一題都會讀取文件顯示當前的答題數據並切換到下一題。
public void actionPerformed(ActionEvent e) { String[] strings=textField.getText().split("="); DoubleStack testStack = new DoubleStack(strings[0]); testStack.analysisString(); String right=testStack.compute(); if(strings.length>1&&strings[1].equals(right)){ textField1.setText("正確!"); curScore.setRightAmount(curScore.getRightAmount()+1); System.out.println(curScore.getRightAmount()); System.out.println(curScore.getWrongAmount()); curScore.setRadioAmount((double)curScore.getRightAmount()/(double)(curScore.getRightAmount()+curScore.getWrongAmount())); System.out.println(curScore.getRadioAmount()); lblNewLabel_1.setText(String.valueOf(curScore.getRightAmount())); label_2.setText(String.valueOf(curScore.getWrongAmount())); label_3.setText(String.valueOf(df.format(curScore.getRadioAmount()*100))+"%"); try { Util.saveScore(curScore); } catch (IOException | ParseException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } else{ textField1.setText("錯誤!正確答案為"+right); curScore.setWrongAmount(curScore.getWrongAmount()+1); curScore.setRadioAmount((double)curScore.getRightAmount()/(double)(curScore.getRightAmount()+curScore.getWrongAmount())); lblNewLabel_1.setText(String.valueOf(curScore.getRightAmount())); label_2.setText(String.valueOf(curScore.getWrongAmount())); label_3.setText(String.valueOf(df.format(curScore.getRadioAmount()*100))+"%"); try { Util.saveScore(curScore); } catch (IOException | ParseException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } textField.setText(Equation.createEquation().toString()); } });View Code
5.2計時器
第一次點擊按鈕時開始計時,第二次點擊按鈕停止計時,第三次點擊按鈕重置。時間以秒計。
public void actionPerformed(ActionEvent e) { curScore=new Score(); lblNewLabel_1.setText("0"); label_2.setText("0"); label_3.setText("0.0%"); try { Util.saveScore(curScore); } catch (IOException | ParseException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } });View Code
5.3多語言支持
通過獲取properties文件中的內容,將字體以對應的形式顯示出來。
public static void changeCharacter(String resource){ ResourceBundle rb = ResourceBundle.getBundle(resource); lblNewLabel.setText(rb.getString("rightAmount")); label.setText(rb.getString("wrongAmount")); label_1.setText(rb.getString("radioAmount")); button_20.setText(rb.getString("reset")); button_19.setText(rb.getString("clear")); button_18.setText(rb.getString("back")); button_23.setText(rb.getString("simply")); button_21.setText(rb.getString("hard")); button_22.setText(rb.getString("english")); button_24.setText(rb.getString("timer")); button_9.setText(rb.getString("next")); }View Code
英文 繁體中文 簡體中文
6 測試運行
其中重置功能可以將答題數據(正確題目、錯誤題目、正確率)重置設為0,清除可將已寫的答案清空,退格可刪除上一個輸入的數據。第二行顯示的上一道題的正確與否。
在添加了括號功能後對其進行的單元測試均通過。
7 合作情況
7.1 吳政楠
這是我第一次以結對的方式完成一次編程。
在後端的實現過程中我扮演了領航員的角色。我從我的搭檔那裏學到了很多東西,他在Java方面有很多項目經驗,很多我之前沒有想明白或者解決不了的問題在我們的討論中常常能迎刃而解。而我在之前沒有實現的括號的功能也得以實現。
而在前端的設計中我扮演了駕駛員的角色。雖然之前在對GUI的呈現方式方面有所分歧,但是在確定了方案後我們便迅速投入了工作。我做事一向拖拉,但是在我搭檔的帶領下,我們在很短的時間內就搭建出了一個基本的框架。在之後的幾次討論中,我們調整了其中設計不合理的部分,並對一些細節問題進行了完善。
7.2 韓華頌
感覺通過結對編程的模式合作還是挺好的,遇到一些問題都會相互請教,而且可以讓我們每一個人都可以從另一個視角去考慮問題。
在後端的編寫過程中,我作為駕駛員與我的搭檔一起編碼。之前我計算表達式的的時候一直想不到特別好的算法,自從跟我的搭檔交流之後才知道了通過逆波蘭的方法來求解會很簡單,省了我不少的時間。後來我的小夥伴還增加了測試的模塊,調試的時候變的更容易了。
我在前端設計時擔任了領航員,因為之前用過windowsBuilder來編寫GUI界面,寫起來節約了不少時間,我的搭檔還把界面做了一些優化,使用戶使用起來更加方便。
8 項目小結
8.1 吳政楠
在這個項目中,我充分感受到了1+1>2的編程體驗。我的Java基礎並不好,這次的合作給我在編程過程中提供了很多新的思路,同時也惡補了之前很多遺忘掉的基礎知識。
同時,在這次合作中,我明白了編程並不是一個人埋頭苦幹就一定能幹好的,有一個能隨時提出意見並給出指導的搭檔可以很大的提高編程的效率。合作中遇到的分歧我們也會理性的分析,並得出一個最優的方案。
這次的合作使我受益匪淺,不僅讓我看到了自己身上很多的不足,同時也給我了一種全新的編程體驗。我也很期待和我的搭檔的下一次的合作。
8.2 韓華頌
這個項目提高了自己的編程能力,和與夥伴的合作協調能力。
在開發的過程中,因為windowsBuilder插件是自動生成GUI代碼的,所以代碼格式很不好,也沒有註釋,不能很容易的讓人理解,以後使用一些自動生成代碼的插件後一定要記住去整理代碼的結構。
通過結對編程,我們優勢互補,大大提高了工作效率,並且彼此相互學到了一些新知識,這門高級軟件工程課還是挺有收獲的,以後一定會好好去學習這門課。
9 結對照片
高級軟件工程第三次作業