四則運算之GUI
Coding克隆地址:https://git.coding.net/lvgx/pair_programming.git
|
目錄:
一、前言
二、計划時間——PSP
三、接口設計
四、接口實現
五、性能分析
六、單元測試
七、異常處理
八、模塊設計
九、模塊對接
十、她
十一、結對編程思考
十二、實際時間——PSP
一、前言
首先我很感謝我的隊友——呂國馨(www.cnblogs.com/lvgx/p/8733486.html),謝謝她清明假期仍在認真的敲代碼,放棄自己休息的時間。第二我要感謝一位大佬,當我對GUI沒絲毫頭緒時,大佬的一篇博客給了我啟發。
下面帶上大佬博客:www.cnblogs.com/mafx/p/8536796.html
二、計划PSP
PSP |
任務內容 |
計划時間(min) |
Planning |
計划 |
30 |
Estimate |
估計這個任務需要多少時間,並規划大致工作步驟 |
30 |
Development |
開發 |
35*60+25 |
Analysis |
需求分析 |
60 |
Design Spec |
生成文檔 |
0 |
Design Review |
設計復審 |
2*60 |
Coding Standard |
代碼規范 |
10 |
Design |
具體設計 |
12*60 |
Coding |
具體編碼 |
2*8*60 |
Code Review |
代碼復審 |
4*60 |
Test |
測試 |
15 |
Reporting |
報告 |
5.5*60 |
Test Report |
測試報告 |
60 |
Size Measurement |
計算工作量 |
30 |
Postmortem& ProcessImprovement Plan |
事后總結, 並提出過程改進計划 |
4*60 |
尤其在編程GUI時候,花費了大量的時間。
三、接口設計
接口設計和低耦合是相輔相成的,接口化設計能大大降低程序的耦合度,低耦合一定離不開接口化設計。個人理解:接口化設計就是模塊化設計,讓不同方法放入到不同類中,並且使得各個類相互獨立,減少關聯性。低耦合和接口化設計差不多,使得各個模塊之間減少依賴性,從而提高容錯率。
我們的設計:我們已經盡我最大的努力,來進行模塊化設計了,比如界面生成和算式生成是相互獨立的,優先級判斷、計算結果和算式生成又是相互獨立的。但是我們的程序還有很多不足,比如界面設計,我們的五個界面都在同一個函數中實現的。原本我們盡力讓他們在不同函數中,但是在繼承時過程中,總是出現錯誤,最后我們還是放棄了。Java的繼承我們還要再學一學。
四、接口實現
本次界面程序一共用到了9個類,14個函數,此9個類的調用關系如下圖:
我們此界面程序的關鍵之處在於監聽器的運用,大概用到了3個監聽器,分別是復選框監聽器、按鈕監聽器、文件監聽器,本打算使用時間監聽器,來計算當前時間和用時,但是發現可以直接調用java中自帶的類,方便起見,就沒有使用。代碼的獨特之處在於:界面套界面。即是亮點又是污點,亮點在於方法簡單,實現方便,容易掌握(靈感來源於:www.cnblogs.com/mafx/p/8536796.html)。同時這也是一個不好之處,導致程序無法分解,耦合度太高,后期維護困難。
五、性能分析
說句實話,自我感覺能完成這個項目就很不錯了,還要什么性能優化呀。。。但是我們已經盡力優化性能了,比如挺高代碼利用率了。比如Puanduan類,和Yunsuan類,我們把它兩生成兩個類,其他類直接調用,減少代碼長度。盡量減少內存開支,比如不定義數組,改用容器,因為數組的每個存儲單元利用率不高。一般數組我們都往大的開,因為怕其不夠用,但是這種方法會導致,大量內存單元沒有被利用。題目要求最大生成10000到題目,如果你開10000大小的數組,當我們只生成10道題時,會有99990個內存沒被利用。我們還盡量減少循環套循環,從而減少時間的消耗。
如何性能分析?百度上說是,進行溢出測試,將代碼進行死循環,使得當CPU達到100%時,查看時間,時間越短,性能越好。
我們的分析方法是:通過JProfiler,進行性能分析。
總體分析圖:包括CPU,內存,線程等等。
性能分析過程:
我們用三組數據分別對三個主要函數進行時間上的測試:
函數一:Algorithm函數,他用時最短,只用了11640微妙,且30%的原因在於文本的輸入與輸出,這是無法避免的,所以未進行優化。
函數二:Algorithm2函數,用時37789微妙,此函數30%的用時是在調用JiSuan函數上,JiSuan的用時主要是在出棧上,也是無法避免的。
函數三:Algorithm1函數用時最長,用時60390微妙,此函數用時主要是循環,此函數中有一個三重循環和大量二重循環,導致了時間過長。從圖像也可以看出,橙色占的比例接近90%(橙色代表,阻礙與消耗,不是正常運行程序時間)。
性能優化:對於循環過多的Algorithm1函數,進行了優化,減少了幾個循環,之后,我們又減少了大量循環,因為老師的需求降低(中間過程可以保證不再范圍之內,這使得我們的程序,更加簡潔)
可見,時間明顯降低!
我們還對界面程序的性能進行分析,和優化,改進,文件也通過ps.close();進行關閉,按F4再一次查看,內存占用率明顯減少,文件也都關閉了,但是仍有內存沒釋放,我們會繼續改進的,性能分析結果如下。
六、單元測試
測試單元代碼:
1 public class Test { 2 3 private static int n=10; 4 private static int m1=1; 5 private static int m2=50; 6 private static int o=4; 7 private static int c=0; 8 private static String s="11+(43-(35-(14+26)))"; 9 10 public static void main(String[] args) { 11 // TODO Auto-generated method stub 12 Command.main(null);// 主界面 13 System.out.println(Algorithm.Algorithm(n, m1, m2, c, o)); //生成題目函數一 14 System.out.println(Algorithm.Algorithm(n, m1, m2, c, o)); //生成題目函數二 15 System.out.println(Algorithm.Algorithm(n, m1, m2, c, o)); //生成題目函數三 16 GUI.main(null); // 中文界面 17 GUI1.main(null); // 英文界面 18 //JiSuan.JiSuan(s); 19 } 20 21 }
我們對9個類進行了測試:采用結合或者獨立的測試方法,來分別觀察其代碼覆蓋率。(表中分別為:函數名、覆蓋率、執行行數、錯過行數、總行數)
第一組數據:
Command.java:這是一個語言選擇窗口。
Algorithm.java:是一個可以生成加減乘除並且帶有括號式子的類。
JiSuan.java:是一個可以計算式子,並且返回結果的類。
Panduan.java:是一個判斷運算符優先級的類
測試結果如下:
第二組數據:
GUI.java和GUI1.java:分別是生成漢語出題窗口和英語出題窗口、漢語上傳文件和英語上傳文件的窗口。測試結果如下:
第三組數據:
YunSuan.java:一個進行簡單加減乘除運算的類。測試結果如下:
第四組數據:
Algorithm1.java:是一個能生成乘除不帶括號和不帶乘除不帶括號式子的類。測試結果如下:
Algorithm2.java:是一個生成不帶乘除帶括號式子的類。測試結果如下:
總體來說,代碼覆蓋率為:91.47%
七、異常處理
異常處理一:就是對輸入出題數、運算符個數、范圍等進行判斷,判斷其是否合法或者超出其范圍。(只展示了,出題數的代碼,其他雷同)
1 try { 2 n1 = Integer.parseInt(n.getText()); 3 if (n1 <= 0 || n1 > 10000) { 4 n.setText("n的范圍不在[1,10000]內,請重新輸入"); 5 return; 6 } 7 flag0 = 1; 8 } catch (Exception a) { 9 n.setText("n的格式不合法,請重新輸入!"); 10 }
對應場景:
異常處理二、文件異常處理
1 try { 2 ps = new PrintStream("result.txt");// 生成文件 3 System.setOut(ps); 4 } catch (Exception e) { 5 System.out.println("文件生成錯誤");// 提示 6 }
對應場景:
點擊出題時,如果文件生成錯誤,將不再生成。
異常處理三:文件過濾
1 FileNameExtensionFilter filter = new FileNameExtensionFilter("war", "xml", "txt", "doc", "docx");
對應場景:
只能找到此格式的文件,其他格式文件,都被過濾了。
異常處理四:編碼異常
1 InputStreamReader read = new InputStreamReader(new FileInputStream(f), "UTF-8");
對應場景:
只能處理UTF-8文件,要不會出現亂碼。
異常處理五:用戶不存在異常
如果你沒有注冊,即文件中沒你的用戶信息,會報用戶不存在異常。
1 int flag = yanZheng(user.getText(), password.getText()); 2 if (flag == 1) { 3 GUI.main(null); 4 } else if (flag == 0) { 5 user.setText("密碼錯誤!"); 6 return; 7 } else { 8 user.setText("賬號不存在!"); 9 return; 10 }
對應場景:
異常處理六:用戶和密碼不匹配
即當用戶存在時,但是密碼輸入和注冊時的不同時,會報密碼錯誤。代碼如上:
對用場景:
異常處理七:用戶已存在
即當注冊過程中,如果該用戶已存在,會報用戶已存在錯誤。
1 int temp = yanZheng(user.getText(), password.getText()); 2 if(temp==0||temp==1) 3 { 4 user.setText("賬號已存在,請重新注冊!"); 5 return ; 6 }
對應場景:
異常處理八:注冊信息不合法
注冊時,對賬號和密碼有一定限制,當超出限制時,會報錯。
1 try { 2 int user1 = Integer.parseInt(user.getText()); 3 if (user1 <= 0 || user1 >= 1000000) { 4 user.setText("用戶名多余6位,或者不合法!"); 5 return; 6 } 7 } catch (Exception a) { 8 user.setText("賬號有多余字符(只能是數字),請重新注冊!"); 9 return; 10 } 11 try { 12 int password1 = Integer.parseInt(password.getText()); 13 } catch (Exception a) { 14 user.setText("密碼有多余字符(只能是數字),請重新注冊!"); 15 return; 16 }
為了方便起見,限制有點嚴格,必須是數字字符串,而且不能超過6位,其實不太合理,但是程序實現很簡單。
對應場景:
八、模塊設計
1、首先先設計一個語言選擇功能,可以進行語言選擇,通過按鈕和調用函數來實現。
1 private JButton jcChina = new JButton("中文");//兩個按鈕,分別生成兩種不同語言的界面 2 private JButton jcEnglish = new JButton("English");//可以用一個數組,存入多種語言,實現多語言轉化 3 jcChina.addActionListener(new ActionListener() {//按鈕監聽器,為了實現中文界面 4 @Override 5 public void actionPerformed(ActionEvent e) { 6 GUI.main(null); 7 } 8 }); 9 jcEnglish.addActionListener(new ActionListener() {//按鈕監聽器,為了實現英文界面 10 @Override 11 public void actionPerformed(ActionEvent e) { 12 GUI1.main(null); 13 } 14 });
2、然后進行出題界面設計,此界面就是簡單的GUI界面設計。
1 JPanel p1 = new JPanel(); 2 p1.setLayout(new GridLayout(4, 2, 5, 5)); 3 p1.add(new JLabel("出題數[1,10000]:")); 4 p1.add(n); 5 p1.add(new JLabel("數值左邊界[1,100]:")); 6 p1.add(m1); 7 p1.add(new JLabel("數值右邊界[50,1000]:")); 8 p1.add(m2); 9 p1.add(new JLabel("運算符數[1,10]:")); 10 p1.add(o);
3、然后進行上傳文件的界面設計,此界面可以直接調用,java中已經有了。
1 JFileChooser chooser = new JFileChooser(); 2 chooser.setMultiSelectionEnabled(true); 3 // 過濾文件類型 4 FileNameExtensionFilter filter = new FileNameExtensionFilter("war", "xml", "txt", "doc", "docx"); 5 chooser.setFileFilter(filter);
4、然后設計答題界面設計,此界面和出題界面類似,但是調用方法不同,在下面我會講到。
1 JPanel panel2 = new JPanel(); 2 JTextField text = new JTextField(10); 3 panel2.setLayout(new GridLayout(3, 2, 5, 5)); 4 label.setText(addProblem()); 5 panel2.add(label); 6 panel2.add(new JLabel("/*為了美觀*/")); 7 panel2.add(new JLabel("請輸入答案:")); 8 panel2.add(text); 9 panel2.add(jbnext); 10 panel2.add(jbsubmit);
5、統計頁面設計,內容設計,改用調用list實現。
1 JPanel panel = new JPanel(); 2 panel.add(new JLabel( 3 "做題總數: " + size + " " + " 正確數:" + rightAnswer + " 用時(S):" + (t2 - t1) / 1000)); 4 setLayout(new GridLayout(100, 1, 5, 5)); 5 for (int i = 0; i < size; i++) { 6 panel.add(new JLabel(list.get(i))); 7 } 8 resultFrame.add(panel);
九、模塊對接
1、語言選擇功能
相當於主函數,它通過按鈕調用GUI和GUI1類
2、出題功能
它也是通過按鈕調用做題界面和上傳界面。
3、做題功能
通過下一題按鈕進行判斷和再次出題,通過按鈕調用統計界面。
4、統計和計時
最終頁面,不進行調用。代碼如下:
5、上傳文件及解析
代碼如下:
調用提交和下一題按鈕,代碼和上面一樣,但是會有一個上傳成功的提示,代碼如下:
6、用戶注冊和登錄功能
沒有注冊的用戶必須注冊后才能進入程序進行答題和出題界面。
通過按鈕對模塊之間進行連接。
十、她
我們原本打算做前端,即Web的四則運算程序,而且她已經完成了,前端開發,如圖:
但是由於我不會套頁,即不能和后端連起來。所以最后放棄了Web項目,改做GUI。讓她白做了一場,慚愧(就當給她個機會,讓她練習練習前端知識了,嘻嘻)。
1、她:優點:技術強;聰明;樂觀。缺點:做事不認真。
2、我:優點:認真,上進,創造性思維強。缺點:模塊化思維欠缺。
十一、結對編程思考
結對編程有好處:
一、可以減輕兩個人的壓力。
二、相互學習、相互指正。
三、增強兩個人的關系,增強合作能力、增強代碼理解能力。
四、分工明確,增加辦事效率。
結對編程有壞處:
一、如果交流不到位,那所做的項目將會功虧一簣。比如這次項目,因為我們前期交流沒有到位,導致Web項目進行到一半,就進行不下去了。
二、兩個人各做各的,導致后期兩者的項目結合比較困難。
三、兩人的分工不均勻,比如技術強的人可能做得就比較多,技術差可能就會抱大腿。
四、要花費大量時間進行交流和解釋項目,畢竟代碼不好看懂。
十二、實際PSP
PSP |
任務內容 |
完成時間(min) |
Planning |
計划 |
60 |
Estimate |
估計這個任務需要多少時間,並規划大致工作步驟 |
60 |
Development |
開發 |
45*60 |
Analysis |
需求分析 |
45 |
Design Spec |
生成文檔 |
0 |
Design Review |
設計復審 |
3*60 |
Coding Standard |
代碼規范 |
15 |
Design |
具體設計 |
12*60 |
Coding |
具體編碼 |
3*8*60 |
Code Review |
代碼復審 |
4*60 |
Test |
測試 |
60 |
Reporting |
報告 |
9*60 |
Test Report |
測試報告 |
0 |
Size Measurement |
計算工作量 |
60 |
Postmortem& ProcessImprovement Plan |
事后總結, 並提出過程改進計划 |
8*60 |
對於附加功能多語言,我們實現了兩種語言的轉換,其實可以通過數組實現多種語言轉換,也可以通過我這種方法實現,即在生成一個界面。這種方法的好處在於簡單,壞處在於代碼比較多,還瑣碎。
對於附加功能多用戶,我們的這個GUI界面程序,可以多人下載,多人使用,實現多用戶同時在線。用戶必須登陸后才能進行上傳題目、出題、做題等功能的使用,還可以統計用戶人數。
參考網站:
www.cnblogs.com/mafx/p/8536796.html //基本的GUI語法
https://zhidao.baidu.com/question/184288577.html //上傳文件語法
https://www.cnblogs.com/happyzm/p/6530384.html //覆蓋率教程