寒假第二次作業作業引導和提示


寒假第二次作業引導和提示

第二次作業涉及的面比較多,如果之前沒有自學相關知識可能會覺得無從下手,以下給大家分析一下這次作業

1. 該以怎樣的順序完成作業,側重點在哪

本次作業主要考察Git、GitHub使用,代碼規范意識,一定的程序設計能力(基於命令行),PSP,以及單元測試和性能分析改進。
在開始時建議先建一個空白文稿統計自己花在各個地方的耗時,方便到時候寫到PSP表格上(關於PSP表格,參考作業附錄)。
之后先別急着寫程序,先看一些Git、GitHub的教程,學會基礎使用之后,按照作業要求fork主倉庫,根據示例目錄結構建好自己的目錄。
建好目錄之后,便可以根據自己使用的語言,根據作業要求,制定代碼規范,代碼規范按照markdown格式,寫到codestyle.md中。
這時便可以開始分析需求、設計模塊。需求分析清楚后便可以開始寫程序。

當你有所產出之后,便可以進行commit,並push到github。作業要求commit 10次並不多,只是讓大家養成習慣。

對於你已經寫好的函數、類,要及時進行單元測試,此次作業要求最少10個測試用例。
單元測試記得滿足“FAIR”原則,即fast(快速)、automated(自動)、isolated(隔離)、repeatable(可重復)。具體使用什么框架並無限制。
單元測試應該隨着程序開發逐漸進行。確保你之后的修改不會導致單元測試的失敗。同時對錯誤情況和邊界條件也應給與測試。

本次作業采用自動測試,所以輸入文件和輸出文件都采用絕對路徑的方式傳入。在自動測試程序中,你們的程序會被當做一個新的進程啟動。
測試的命令和題目給出的並無太多區別。只是到時候日志會替換成更復雜的日志。

整個程序寫完之后,測試也全部完成之后。可以進行一些單元測試覆蓋率分析,性能分析。

這一切都完成后便可以在github 上pr(pull request)你的倉庫到主倉庫。

這次作業的目的是為后邊的“結對”、“團隊”編程打好基礎。這一切相關的技術也是貫穿軟件工程整個生命周期的。
如果你時間比較緊張,基礎較薄弱,建議你重點掌握好github、代碼規范、PSP、單元測試,程序力爭通過基礎測試(基礎list命令【30%】:僅僅攜帶-log、-out參數)。
如果你還學有余力,可以去學習如何使用構建工具進行項目的構建,如maven、gradle(但是確保你提交的倉庫符合作業要求)。

2、需求簡要分析

這次程序主要考察輸入輸出,文本處理。
文本處理推薦采用正則表達式的方式。如~/(\S+) 新增 感染患者 (\d+)人/匹配福建 新增 感染患者 2人
對於模塊設計,應該小心。
雖然此次作業僅僅只需要完成list命令,但是從工程角度考慮,你應確保你的程序是可以擴展的。
你也許會用if ("list".equals(cmd)){}這樣的方式來判斷命令是否正確,但它雖然簡單,卻不利於擴展。
嘗試使用設計模式中的命令模式

此外如果你在處理日志時采用了正則,那么你是通過什么樣的方式來判斷日志符合那個正則表達式呢?
使用switch方式並不是好的方式。
嘗試使用設計模式中的狀態模式、責任鏈模式,將對應不同的日志和不同的操作集成到一個LogLine中,並將他們鏈接起來。
以下可能是個提示:

/**
 * 不同類型日志行
 */
class LogLine {
    private Pattern reg;
    private LogHandle handle;
    
    // ...
}

此次作業的單元測試需要一些技巧,可以寄托於函數來測試,比如你測試list函數:public void list(String logPath, Sting outPath, Date date, List<String> province, List<ArgType> type)
這樣你可以將命令分析程序解構出來,同時方便進行單元測試。(當然這還不是好的設計,因為日志讀取不應該放進list,參數核驗也是)
但單元測試就會變的輕松一些:assertEquals(list(...), new File(...).text)

你怎么把它設計的更直觀?
將你的命令解析獨立出來,它提供一個使用字符串構造命令的方式(甚至可以從文件中讀取命令來執行):


/**
 * 解析命令行參數
 */
class CmdArgs {
    String[] args

    /**
     * 傳入命令行參數數組構造
     * @param args
     */
    CmdArgs(String[] args) {
        //...
    }

    /**
     * 傳入命令構造,可以設置無用的前綴,如`groovy Lib`
     * @param argsStr
     * @param noUseInStart
     */
    CmdArgs(String argsStr, String noUseInStart = '') {
        //...
    }

    /**
     * 遍歷文件的命令,調用閉包
     * @param fileName
     * @param noUseInStart
     * @param closure{ String line -> }
     */
    static void eachLine(String fileName, String noUseInStart = '', Closure closure) {
        //...
    }

    /**
     * 獲取命令
     * @return
     */
    String getCmd() {
        //...
    }

    /**
     * 獲取某個命令行參數的值,多個值只會返回第一個
     * @param key
     * @return
     */
    String argVal(String key) {
        //...
    }

    /**
     * 獲取某個命令行參數的值,返回列表
     * @param key
     * @return
     */
    def argVals(String key) {
        //...
    }

    /**
     * 判斷該命令是否有對應的參數
     * @param key
     * @return
     */
    boolean has(String key) {
        //...
    }
}

這是一個可能的流程:
SystemIn -> CmdArg -> CmdArgCheck -> LogParser -> DoCmd -> DoList -> FileOut

當SystemIn 換成 TestIn或者 GUI In它也能正常工作,而不需要做過多的更改。

3、IDEA簡要教程

  1. 導入github項目:

  2. commit

  3. github push

  4. 導入junit

    之后設置你下載的junit包即可。

  5. 使用junit 進行單元測試

    繼承TestCase即可。方法名需要滿足:1、public 2、返回值void 3、方法名以test開頭

  6. 代碼覆蓋率分析

  7. Jprofiler性能分析

歡迎加入我的技術交流群:


免責聲明!

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



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