第四次軟工作業——結對編程


GIT地址 GITHUB克隆地址
結對伙伴 余睿哲
伙伴學號 201831061417
伙伴博客地址 地址

一、PSP表格


二、接口的設計與實現過程

設計:

共五大類,其中計算方法類和命令行翻譯類兩個類需要設計對應的接口。

詳細內容見下面思維導圖(如果圖片看不清可以適當放大網頁觀看

各類之間的關系

CountMethodImpl類 為Main類提供各種算法

TranslateCommandImpl類 則翻譯Main類傳過去的命令行指令,並返回需要的參數

WriteFile類 主要用於文件讀寫

Test類 用於測試各種類中的方法能否正確實現

Main類 中執行主函數,集成所有功能。

關鍵函數及實現方法(見思維導圖)

程序運行結果

注:有效行數與看到的行數不同的原因:文檔窗口的大小不同,會導致顯示的行數不同,如果文檔窗口足夠長,則該文章(測試文章)可顯示為一行

用到的幾種設計理念

Interface Design

為兩個比較重要,且內部函數較多的類設計了接口

Loose Coupling

設計了五大類,將各個部分分開,想要加減功能可以在對應的類中進行更新,對整體影響較小

Information Hiding

使用一些常量將ASCII碼、條件語句以及循環的參數保存起來,即隱藏了數據也提高了代碼的可讀性。


三、代碼復審

編碼規范

參考《阿里巴巴JAVA開發手冊》

開始閱讀

IDEA編譯器可以下載審查插件

插件掃描結果,即還存在的問題:

改正后:

還存在一定的問題是因為:

1、有一個類為最早寫的測試類,里面有較多直接使用的數字(以后會多加注意)。

2、有變量定義為numberM和numberN,是符合小寫駝峰命名法的,是插件掃描判斷錯誤。


四、性能改進

性能改進

接口實現的函數中,大多數都需要用到循環,循環的時間復雜度不算多,但也不算少。所以在循環中減少不必要的循環,不如在需要跳出循環時跳出循環,減少循環次數等等,即可減少一定的時間消耗,從而提高性能。

性能工具:JProfiler(IDEA的性能測試插件)

安裝方法

性能分析圖

主函數因為集成了所有工具類的方法,所以消耗最大

主函數代碼如下

public static void main(String[] args) {
	//輸入命令行
	Scanner scanner = new Scanner(System.in);
	String cmd = scanner.nextLine();
	//創建需要的對象
	TranslateCommandImpl translate = new TranslateCommandImpl();
	CountMethodImpl method = new CountMethodImpl();
	WriteFile writeFile = new WriteFile();
	//得到需要的參數
	String inFile = translate.returnInFile(cmd);
	String outFile = translate.returnOutFile(cmd);
	int numberM = translate.returnNumberM(cmd);
	int numberN = translate.returnNumberN(cmd);
	//能否讀到文件,不能則停止
	try {
		InputStream in = new FileInputStream(inFile);
	}catch (IOException e) {
		System.out.println("文件位置有誤!");
		return;
	}
	//用於保存各種數據
	int characters, words, lines;
	//詞頻Map中的長度
	int length;
	//判斷有無-i, -o指令
	String noFile = "null";
	if(noFile.equals(inFile) || noFile.equals(outFile)) {
		System.out.println("輸入或者輸出不能為空!");
		return;
	}
	//用於保存單詞集
	List<String> strings;
	//定長單詞集
	List<String> lengthWords;
	characters = method.countCharacterNumber(inFile);
	strings = method.countWordNumber(inFile);
	words = strings.size();
	lines = method.countLine(inFile);
	lengthWords = method.statisticsWord(strings, numberM);
	//得到詞頻的Map
	List<Map.Entry<String, Integer>> frequency = method.countWordsFrequency(strings);
	//保存定長詞頻
	List<Map.Entry<String, Integer>> neededFrequency = new ArrayList<>();
	//得到其長度,方便遍歷
	int maxLength = 10;
	length = frequency.size();
	//如果長度大於10,則把長度變成10
	if(length > maxLength) {
		length = 10;
	}
	//打印結果
	System.out.println("字符總數是:"+characters);
	System.out.println("有效單詞數是:"+words);
	System.out.println("有效行數是:"+lines);
	System.out.println("單詞的出現頻率從高到低依次是:");
	for(int i=0; i<length; i++) {
		System.out.println(frequency.get(i));
	}
	if(numberM > 0) {
		System.out.println("定長為 "+numberM+" 的單詞是:"+lengthWords);
	}
	//如果參數n大於Map中的大小,則打印有效個。
	if(numberN > length) {
		numberN = length;
	}
	if(numberN > 0) {
		System.out.println("出現評率最高的前"+numberN+"個單詞依次是:");
		for(int i=0; i<numberN; i++) {
			System.out.println(frequency.get(i));
			neededFrequency.add(frequency.get(i));
		}
	}
	//寫入文件
	writeFile.writeFile(outFile, characters, words, lines, lengthWords, neededFrequency);
}

五、單元測試及其覆蓋率展示

測試有效行的計算

函數構造思路:得到數據后,打印文章行數

數據構造思路:文章中有空行,看程序能否正確判斷

測試有效單詞的讀取

函數構造思路:得到數據后,統計有效單詞數后打印

數據構造思路:文章中有部分非有效單詞,看程序能否成功判斷並存入單詞集合中。

測試命令行參數的獲取

函數構造思路:給定一條命令行指令,看能否正確地獲得參數

數據構造思路:給定各種形式的命令行進行測試,看能否正確獲得參數;以及命令行有問題時能否正確報錯。


六、異常處理說明

注:異常處理都在主函數中直接進行測試

異常一:命令行沒有 -i 或 -o指令

異常二:無法讀取到文件


七、結對過程

描述:

這次很幸運能夠找到也同樣是寫JAVA的同學余睿哲。分工明確,因為我在一開始就對這個程序的編寫有比較明確的思路,所有完成了大部分代碼的編寫;相應的他完成了很多代碼的審計工作。結對編程讓我感到一個復雜程序的編寫,因為兩個人的合作與努力變得簡單了。結對期間沒有發生任何矛盾,每個人都把自己的做的那部分任務做到了最好。代碼的編寫期間也有過阻礙,通過兩個人的共同思考解決了問題。讓我真切的感受到1+1>2。

照片如下:


免責聲明!

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



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