系统分析与设计结对项目———Wordcount
系統(tǒng)分析與設(shè)計(jì)結(jié)對(duì)項(xiàng)目———Wordcount
?
?
? ? ?合作者:201631062513、201631062511
? ? ?本次作業(yè)要求鏈接地址:https://edu.cnblogs.com/campus/xnsy/2018Systemanalysisanddesign/homework/2188
? ? ?本次作業(yè)代碼鏈接地址:https://gitee.com/linsai/WordCount
?一、代碼審核及合并
? ? ? ? ?對(duì)于代碼的審核,主要是自審和互審,在第一次個(gè)人項(xiàng)目中我們并沒有對(duì)自己的代碼進(jìn)行審核,而且測(cè)試也沒有做的很完善? 所以在結(jié)對(duì)項(xiàng)目中我們要對(duì)自己的項(xiàng)目進(jìn)行審核以及測(cè)試,最后將兩個(gè)人的代碼合并實(shí)現(xiàn)該項(xiàng)目的擴(kuò)展和高級(jí)功能,最后我們對(duì)添加高級(jí)功能后的測(cè)試就輕松許多。具體的審核如下表:
?CODER01:
| 代碼自審 | 代碼互審 | 代碼合并 |
| 獨(dú)自檢查文件名,邏輯、以及是否存在不合法的操作 | 首先運(yùn)行代碼,查看代碼是否可以通過并達(dá)到預(yù)期的目的 | 將自審和互審的結(jié)果進(jìn)行討論把穩(wěn)定的部分代碼進(jìn)行標(biāo)記, 與CODER02的代碼進(jìn)行比較, 把穩(wěn)定性搞的代碼留下,并在 任一一個(gè)單獨(dú)項(xiàng)目上進(jìn)行合并,最后兩人一起完成審核 測(cè)試,完成擴(kuò)展功能 |
| 檢查代碼在編碼格式上是否存在問題 | 其次是構(gòu)建測(cè)試類,調(diào)用關(guān)鍵的方法去執(zhí)行,查看是否能通過運(yùn)行或者拋出異常 | |
| 檢查在關(guān)鍵代碼上是否有異常拋出 | 最后就是測(cè)試代碼的穩(wěn)定性,通過多個(gè)文件對(duì)代碼進(jìn)行測(cè)試,查看是否出現(xiàn)異常 |
??
?
?CODER02:
| 代碼自審 | 代碼互審 | 代碼合并 |
| 檢查項(xiàng)目中的命名、語法,格式是否合乎規(guī)范 | 首先運(yùn)行代碼,查看代碼是否可以通過并達(dá)到預(yù)期的目的 | 將自審和互審的結(jié)果進(jìn)行討論,把穩(wěn)定的部分代碼進(jìn)行標(biāo)記,與CODER01的代碼進(jìn)行比 較,把穩(wěn)定性搞的代碼留下,并在任一一個(gè) 單獨(dú)項(xiàng)目上進(jìn)行合并,最后兩人一起完成 審核,測(cè)試,完成擴(kuò)展功能 |
| 檢查代碼編碼格式,關(guān)鍵代碼是否有異常拋出 | 其次是構(gòu)建測(cè)試類,調(diào)用關(guān)鍵的方法去執(zhí)行,查看是否能通過運(yùn)行或者拋出異常 | |
| 查看代碼的可讀性,以及注釋量 | 最后就是測(cè)試代碼的穩(wěn)定性,通過多個(gè)文件對(duì)代碼進(jìn)行測(cè)試,查看是否出現(xiàn)異常 |
二、實(shí)現(xiàn)擴(kuò)展功能
? ? ? ?在個(gè)人項(xiàng)目上,幾乎只是實(shí)現(xiàn)了基礎(chǔ)功能: 統(tǒng)計(jì)源文件里面的單詞數(shù)、字符數(shù)、以及行數(shù),但是在java 源文件里面還存在大?量的注釋代碼,空行碼,需要統(tǒng)計(jì)以及采用遞歸處理在該目錄下符合條件的文件,該功能的測(cè)試和審查均按照上表進(jìn)行
具體的實(shí)現(xiàn)過程參看下表:
?
?
psp表格:
| SP2.1 | PSP階段 | 預(yù)估耗時(shí) (分鐘) | 實(shí)際耗時(shí) (分鐘) |
| Planning | 計(jì)劃 | ?30 | ?50 |
| · Estimate | · 估計(jì)這個(gè)任務(wù)需要多少時(shí)間 | ?150 | ?200 |
| Development | 開發(fā) | ?100 | ?120 |
| · Analysis | · 需求分析 (包括學(xué)習(xí)新技術(shù)) | ?100 | ?130 |
| · Design Spec | · 生成設(shè)計(jì)文檔 | ? | ? |
| · Design Review | · 設(shè)計(jì)復(fù)審 (和同事審核設(shè)計(jì)文檔) | ?30 | ?50 |
| · Coding Standard | · 代碼規(guī)范 (為目前的開發(fā)制定合適的規(guī)范) | ?30 | ?50 |
| · Design | · 具體設(shè)計(jì) | ?30 | ?40 |
| · Coding | · 具體編碼 | ?150 | ?200 |
| · Code Review | · 代碼復(fù)審 | ?30 | ?40 |
| · Test | · 測(cè)試(自我測(cè)試,修改代碼,提交修改) | ?50 | ?70 |
| Reporting | 報(bào)告 | ?30 | ?50 |
| · Test Report | · 測(cè)試報(bào)告 | ? | ? |
| · Size Measurement | · 計(jì)算工作量 | ?30 | ?30 |
| · Postmortem & Process Improvement Plan | · 事后總結(jié), 并提出過程改進(jìn)計(jì)劃 | ?30 | ?30 |
| ? | ? ? 合計(jì) | ?790 | ?? ?1200 ? |
?
? ? ? ? 表格分析 :上面的一些過程包含了高級(jí)功能(圖像化界面),該表格也反映了我們?cè)谠诮Y(jié)對(duì)上對(duì)于代碼復(fù)審以及編碼花費(fèi)了大量的時(shí)間,主要是在復(fù)審時(shí)花的時(shí)間比較多,各自都在解決各自的問題和討論,無法達(dá)到一致,因此也導(dǎo)致后面的擴(kuò)展功能也需要兩人配合完成,畢竟是把代碼進(jìn)行了合并,但是大部分采用了coder02同學(xué)的代碼,他的代碼相對(duì)于coder01的來說顯得非常規(guī)范,總的來說,顯得比較繁瑣和復(fù)雜。
?
三、高級(jí)功能實(shí)現(xiàn)
? ? ? ??該結(jié)對(duì)項(xiàng)目的高級(jí)功能是將查詢的結(jié)果用圖像化界面顯示出來,由于前面的個(gè)人項(xiàng)目采用的編程語言是java,所以,用的是java的圖形化界面,基于AWT框架、布局管理器 java swing 、AWT事件處理等技術(shù)來實(shí)現(xiàn)圖形化界面。其次是在windows命令行中輸入 wc.exe? -x 命令,將直接顯示wc的圖像化界面,然后就可以進(jìn)行查詢操作,在界面上打開指定源程序文件過后,可以直接全部查詢或者分類查詢。
圖像化界面截圖如下:
?
?利用遞歸循環(huán)遍歷該目錄下的.c源程序文件,實(shí)現(xiàn)其擴(kuò)展功能:
利用遞歸循環(huán)遍歷該目錄下的.c源程序文件,實(shí)現(xiàn)所有功能:
?
?停用表測(cè)試功能:
創(chuàng)建TestEfficent測(cè)試類,測(cè)試代碼覆蓋率
?四、項(xiàng)目的關(guān)鍵代碼
高級(jí)功能實(shí)現(xiàn)關(guān)鍵代碼
import java.awt.BorderLayout; import java.awt.EventQueue;import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.ButtonGroup; import javax.swing.JButton; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.awt.event.ActionEvent; import java.awt.GridLayout; import java.awt.TextArea;import javax.swing.JTextField; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JTextPane; import javax.swing.JTabbedPane; import javax.swing.JEditorPane; import javax.swing.JFileChooser; import javax.swing.JTextArea; import java.awt.Font; import java.awt.Color; import java.awt.SystemColor; import javax.swing.JRadioButton;public class FrameTest extends JFrame {private JPanel contentPane;private JTextField textField;private JTextField textField_1;private JTextArea textArea;/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {FrameTest frame = new FrameTest();frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/*** Create the frame.*/public FrameTest() {setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 639, 444);contentPane = new JPanel();contentPane.setForeground(new Color(0, 255, 255));contentPane.setBackground(new Color(153, 180, 209));contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));setContentPane(contentPane);contentPane.setLayout(null);textField = new JTextField();textField.setBounds(64, 41, 292, 24);contentPane.add(textField);textField.setColumns(10);ButtonGroup buttonGroup2 = new ButtonGroup();JButton button = new JButton("\u9009\u62E9\u6587\u4EF6\u8DEF\u5F84");button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {JFileChooser chooser = new JFileChooser(); // 設(shè)置選擇器chooser.setMultiSelectionEnabled(true); // 設(shè)為多選int returnVal = chooser.showOpenDialog(button); // 是否打開文件選擇框System.out.println("returnVal=" + returnVal);if (returnVal == JFileChooser.APPROVE_OPTION) { // 如果符合文件類型 String filepath = chooser.getSelectedFile().getAbsolutePath();// 獲取絕對(duì)路徑//String filename = chooser.getSelectedFile().getName();filepath = filepath.replaceAll("\\\\","/");textField.setText(filepath);//textField_1.setText(filename + "統(tǒng)計(jì)結(jié)果為:");/*System.out.println(filepath);System.out.println("You chose to open this file: " + chooser.getSelectedFile().getName()); // 輸出相對(duì)路徑 */}}});button.setBounds(422, 40, 123, 27);contentPane.add(button);JCheckBox charcount = new JCheckBox("\u5B57\u7B26\u6570");charcount.setBounds(25, 142, 93, 27);contentPane.add(charcount);buttonGroup2.add(charcount);JCheckBox wordcount = new JCheckBox("\u5355\u8BCD\u6570");wordcount.setBounds(152, 142, 81, 27);contentPane.add(wordcount);buttonGroup2.add(wordcount);JCheckBox lincount = new JCheckBox("\u884C\u6570");lincount.setBounds(279, 142, 72, 27);contentPane.add(lincount);buttonGroup2.add(lincount);JButton button_1 = new JButton("\u5F00\u59CB\u67E5\u8BE2");button_1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getSource()==button_1){WordCount WC=new WordCount(0,0,0,0,0,0);String path=textField.getText();String inputFile=path;String stopFile="result.txt";try {WC.wc(inputFile, stopFile);} catch (IOException e1) {// TODO Auto-generated catch block e1.printStackTrace();}//獲取參數(shù)路徑String result = "單詞數(shù):"+WC.getWordCount();String result1 = "字符數(shù):"+WC.getCharCount();String result2 = "行數(shù):"+WC.getLineCount();String result3 = "代碼行/空行/注釋行:"+WC.getCodeCount()+","+WC.getSpaceCount()+","+WC.getNoteCount();//textArea.append(result+"\n"+result1+"\n"+result2+"\n"+result3);if(charcount.isSelected()){textArea.append(result1+"\n");}if(wordcount.isSelected()){textArea.append(result+"\n");}if(lincount.isSelected()){textArea.append(result2+"\n");}}}});button_1.setBounds(422, 142, 113, 27);buttonGroup2.add(button_1);contentPane.add(button_1);JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);tabbedPane.setBounds(14, 23, 5, 5);contentPane.add(tabbedPane);JLabel label = new JLabel("\u7ED3\u679C\u8F93\u51FA\uFF1A");label.setBounds(14, 200, 87, 18);contentPane.add(label);JLabel lblWc = new JLabel("WC\u5728\u7EBF");lblWc.setBounds(14, 10, 72, 18);contentPane.add(lblWc);textArea = new JTextArea();textArea.setBounds(14, 231, 392, 141);contentPane.add(textArea);textField_1 = new JTextField();textField_1.setBounds(14, 231, 392, 141);contentPane.add(textField_1);textField_1.setColumns(10);JLabel label_1 = new JLabel("\u5206\u7C7B\u67E5\u8BE2\uFF1A");label_1.setBounds(14, 103, 87, 18);contentPane.add(label_1); } }擴(kuò)展功能部分代碼:
/統(tǒng)計(jì)功能字符數(shù)、單詞數(shù)、行數(shù)、代碼行/空行/注釋行 public static void wc(String inputFile,String stopFile) throws IOException{String lineString = null; String[] buffer=null; //文件每行String[] buffer1 = null;//stoplistboolean isNote = false;int notNote=0;//讀取停用詞表if(useStop){File dirr=new File(stopFile);BufferedReader bff = new BufferedReader(new FileReader(dirr));while((lineString=bff.readLine())!=null){buffer1=lineString.split(",| ");}bff.close(); }lineString = null;// 讀取輸入文件inputFileFile dir=new File(inputFile);BufferedReader bf = new BufferedReader(new FileReader(dir)); while((lineString=bf.readLine())!=null){//遇到 , 空格 就結(jié)束賦值buffer=lineString.split(",|;| ");for(int i=0;i<buffer.length;i++){//使用停用詞表則剔除詞表內(nèi)單詞,不用則不踢if(useStop){if(!buffer[i].equals("")&&!inStop(buffer[i], buffer1)){wordCount++;} }else{wordCount++;}}//if(buffer.length!=1)lineCount++;charCount+=(lineString.length()+1);lineString=lineString.trim();//空行,一個(gè)字符的也算空行if (lineString.matches("^[//s&&[^//n]]*$")||lineString.length()==1) { spaceCount++; } //注釋/*的開始else if (lineString.startsWith("/*") && !lineString.endsWith("*/")||((lineString.startsWith("{/*")||lineString.startsWith("}/*"))&&!lineString.endsWith("*/"))){noteCount++;isNote=true;}//沒有遇到*/else if(isNote&&!lineString.endsWith("*/")&&!lineString.startsWith("*/")) { notNote++;noteCount++;}//遇到*/else if (isNote == true && (lineString.endsWith("*/")||lineString.startsWith("*/"))) {noteCount++;isNote=false;}//注釋行else if (lineString.startsWith("//")|| lineString.startsWith("}//")||lineString.startsWith("{//")||((lineString.startsWith("{/*") ||lineString.startsWith("}/*")||lineString.startsWith("/*"))&& lineString.endsWith("*/"))) { noteCount++;}else{codeCount++;} }bf.close();noteCount-=notNote;codeCount+=notNote;}//判斷是否在停用詞表內(nèi) public static boolean inStop(String str,String[] buffer){int count=0;for(int i=0;i<buffer.length;i++){if(str.equals(buffer[i])){count++;}}if(count>0)return true;elsereturn false; }//遍歷文件 public static List<File> getFile(File dir) { List<File> files = new ArrayList<File>();// 此文件下的所有文件和文件夾集合File[] subs = dir.listFiles(); for (File file : subs) { if (file.isFile() && file.getName().endsWith(endStr)) {// 把獲取到的后綴文件添加到集合中,可以是任何后綴文件 files.add(file); } else if (file.isDirectory()) //如果是目錄,就進(jìn)行遞歸 files.addAll(getFile(file)); } return files; } }五、設(shè)計(jì)流程圖
?
六項(xiàng)目總結(jié):
? ? ? ? ?本次的結(jié)對(duì)項(xiàng)目給我們最大的影響實(shí)在合作方面,因?yàn)槲覀円盐覀兊拇a進(jìn)行互審和合并,在完成的過程
中會(huì)出現(xiàn)很多的錯(cuò)誤,畢竟代碼是兩個(gè)人的,所以我們就先負(fù)責(zé)自己原來代碼,在自己原來代碼的基礎(chǔ)上嘗試實(shí)現(xiàn)
擴(kuò)展功能,然后在做圖形化界面。現(xiàn)在了解到讀別人的代碼是非常難的,思路不同,編碼規(guī)范也不一樣,自己有自
己的風(fēng)格。還是需要不斷的溝通嘗試去理解別人的代碼,但是兩個(gè)人一起配合做還是有非常好的,大大提高了編程
的效率,而且有問題也可以一起解決,可以嘗試不同的思路。
轉(zhuǎn)載于:https://www.cnblogs.com/3106Likai/p/9792015.html
總結(jié)
以上是生活随笔為你收集整理的系统分析与设计结对项目———Wordcount的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bzoj4472: [Jsoi2015]
- 下一篇: 使用django创建一个单表查询的图书管