一、Github地址:https://github.com/734635746/WC
二、PSP表格
PSP2.1 | Personal Software Process Stages | 預估耗時(分鍾) | 實際耗時(分鍾) |
---|---|---|---|
Planning | 計划 | 30 | 30 |
· Estimate | · 估計這個任務需要多少時間 | 30 | 30 |
Development | 開發 | 1130 | 970 |
· Analysis | · 需求分析 | 100 | 80 |
· Design Spec | · 生成設計文檔 | 40 | 50 |
· Design Review | · 設計復審 | 40 | 60 |
· Coding Standard | · 代碼規范 | 20 | 30 |
· Design | · 具體設計 | 80 | 60 |
· Coding | · 具體編碼 | 700 | 600 |
· Code Review | · 代碼復審 | 30 | 30 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 120 | 60 |
Reporting | 報告 | 120 | 130 |
· Test Report | · 測試報告 | 60 | 50 |
· Size Measurement | · 計算工作量 | 20 | 30 |
· Postmortem & Process Improvement Plan | · 事后總結, 並提出過程改進計划 | 40 | 40 |
合計 | 1280 | 1130 |
三、解題思路
在仔細閱讀完項目的需求后,我發現了整個項目的流程主要就是接收具體的參數對指定的文件進行具體的操作。
1.文件操作對象的設計
由於對文件的處理是通過不同的參數來實現不同的處理、而且這些不同的操作基本是只依賴於處理參數和文件路徑。我首先想到的是采用多態的思想,將這些不同的操作封裝成不同的處理類並且讓這些處理類實現同一個接口(FileProcessor)、這樣做可以通過接口調用公共方法而實現不同的處理行為、提高了代碼的可擴展性。
2.簡單工廠模式
如果直接通過new的方式來創建文件處理對象那么將會使代碼冗余、不易瀏覽與維護。所以我采用了簡單工廠模式,通過具體的操作參數(-a、-l、-w、-c)去工廠獲取對應的文件處理對象進行處理。由於采用了簡單工廠設計模式了,所以外界只管通過參數來獲取對象,而不用關心對象的具體創建,利於整個軟件體系結構的優化。
3. 處理結果的返回
一開始我想直接將處理的結果通過字符串的方式返回。但感覺有些違反了對修改開放-對擴展開放的原則,如果以后的返回的信息多樣化了之后,代碼將會很難修改。所以我將處理返回結果設計成一個類(FileResult).將需要返回的內容作為屬性封裝在對象中返回。再之后,我考慮到文件的處理並不一定成功還需要返回錯誤對象。所以我設計一個錯誤返回類(ErrorResult),同時讓處理結果類和錯誤返回類實現接口(result)。便於結果的統一處理。
4. 錯誤類型的枚舉
考慮到程序的可讀性以及后期的擴展性,設計了一個錯誤類型的枚舉(ErrorTypeEnum),用於枚舉程序中有可能出現的錯誤,並且在錯誤返回類中支持了錯誤類型枚舉。提高的程序的可讀性。
5. 遞歸處理的實現
到這里實現的還是對於當個指定文件的處理。對於實現處理多個文件的功能來說、遞歸是個好的思想。將“-s”作為第一個參數可以開啟遞歸處理。對於用戶輸入的目錄/文件,首先將會根據處理參數(-a、-l、-w、-c)去工廠獲取對應的文件處理對象,然后調用遞歸處理器(RecursiveProcessor)來遞歸地獲取目錄下的所有文件路徑,再通過剛才獲取的文件處理對象進行批量處理,返回一個處理結果的列表。
6.通配符的支持
程序可以通過“-s”參數配合實現通配符匹配文件的功能。具體實現思路是判斷用於輸入的文件url是否含有“*”、"?",如果有將進行通配符匹配。
首先截取url的目錄部分通過遞歸處理獲取目錄下的所有文件類型的url, 然后通過一個工具函數將含有通配符的文件名轉成一個正則表達式。最后采用Pattern類進行模式匹配,將匹配的文件路徑進行處理放回處理結果集。
8. 圖形界面
圖形界面的設計比較簡單,就是通過設計一個JFrame通過jFileChooser控件選擇文件進行處理,再將處理結果顯示在TextArea控件上,底層還是調用工廠來獲取處理對象進行處理。
8. 主類
主類主要是負責接收處理參數調用不同的文件處理對象進行處理然后接收處理結果進行顯示。
總體來說這次項目的完成還是比較順利,但是代碼還是有一定的冗余性可以繼續進行優化。最主要就是在開始編碼之前要先設計好大概的處理流程以及模塊划分。使用學過的知識來優化代碼,盡量降低代碼的耦合性,提高代碼的可讀性、可擴展性和易修改性。
四、設計實現過程
代碼主要分成個 主類、錯誤枚舉、 處理結果類 、處理工廠及其處理類 、工具類、圖形界面類 六個部分
主要調用流程:
五、測試運行
測試文件包括:一個空文件、一個只有一個字符的文件、一個只有一個單詞的文件、一個標准的java源文件、一個多目錄嵌套的文件
5.1 測試非遞歸的功能(-l、-a、-w 、-c)
@org.junit.Test
public void testFunction_2() throws IOException {
String url = "F:\\file\\k.txt";
String[] params= new String[]{"-a","-l","-w","c"};
for (String param : params) {
testOneProcessor(url,param);
}
}
private void testOneProcessor(String url, String param) throws IOException {
FileProcessor processor = FileProcessorFactory.getFileProcessorOf(param);
result result = processor.disposeFileOf(url);
result.showResult();
}
5.1.1 測試空文件
5.1.2 測試一個只有一個字符的文件
5.1.3 測試一個只有一個單詞的文件
5.1.4 測試標准java源文件
5.1.5 測試不存在的文件
5.2 測試非遞歸的功能(-s -a/-w/-l/-c)
5.2.1 測試多目錄嵌套的文件
@org.junit.Test
public void test() throws IOException {
String url = "F:\\file\\k.txt";
String[] params= new String[]{"-a","-l","-w","c"};
for (String param : params) {
testRecursive(url,param);
}
}
private void testRecursive(String url, String param) throws IOException {
FileProcessor processor = FileProcessorFactory.getFileProcessorOf(param);
RecursiveProcessor processor1 = new RecursiveProcessor(processor, url);
List<result> result = processor1.getDisposeResult();
for (com.lyb.bean.result result1 : result) {
result1.showResult();
}
}
5.2.2 測試多目錄嵌套的文件配合通配符?
@org.junit.Test public void testFunction2() throws IOException { String url = "F:\\file\\?.txt"; FileProcessor processor = FileProcessorFactory.getFileProcessorOf("-a"); RecursiveProcessor processor1 = new RecursiveProcessor(processor, url); List<result> result = processor1.getDisposeResult(); for (com.lyb.bean.result result1 : result) { result1.showResult(); } }
5.3 測試圖形化功能(-x)
經過驗證所有處理結果與預期結果一致
代碼覆蓋率:
由於圖形化界面的測試是單獨測試而不是在單測中進行,所以代碼覆蓋率中圖形界面的代碼覆蓋率為0。也由於這樣,所以一些在圖形界面中使用的api沒有覆蓋到。
六、項目總結
本次項目選用java作為開發語言、maven作為構建工具、junit做單元測試、jacoco做代碼覆蓋率檢查插件。
遵循一定的代碼開發規范、努力使用面向對象的思想解決問題。運用軟件工程的方法努力寫出較為規范的代碼、盡量降低模塊的耦合度。但是還是存在不足,代碼的冗余度還是比較高。總體來說這是一個比較好的練手項目,即復習了java中的IO流使用,也學着運用軟件工程的思想來規范開發。