天天看點

【助教】第三次程式設計作業(草稿)

大家寫了不少四則運算的練習,這些代碼都各有特色,大家寫的 “軟體” 也有一定的用處。 如果我們要把這個功能放到不同的環境中去 (例如,指令行,windows 圖形界面程式,網頁程式,手機App), 就會碰到困難, 因為目前代碼的普遍問題是代碼都散落在main() 函數或者其他子函數中,我們很難把這些功能完整地剝離出來,作為一個獨立的子產品滿足不同的需求。

我們看到,不同的代碼解決不同層面的問題,有些是内部資料的計算 (例如四則運算);有些是和使用者輸入相關的 (例如 scanf,cin,圖形界面的輸入字段),有些是和資料的展現相關的 (例如 printf ,cout,println),有些是和程式所在平台的架構相關的(例如 main 函數,并不是所有的程式都需要某個特定格式的main)。 這就需要我們對軟體的架構做一些整理和優化。

是以,接下來我們要做的是:

在我們第三次練習中,還是采用結對程式設計的方式 ,但是大家必須換一個隊友,我們會了解到子產品化程式設計,資訊隐藏,接口設計,TDD,等。

大家把四則運算的計算功能包裝在一個子產品中 (這個子產品可以是一個類 Class, 一個DLL,等等), 為了友善起見,我們叫它 “計算核心” 子產品, 這個子產品至少在兩個地方可以使用:

測試程式,這個可以是一個指令行的程式,或者是JUnit 的架構,或者是Visual Studio 單元測試的架構。這樣,我們在算法層級保證了這個子產品的正确性。

實際的軟體,這是傳遞給最終使用者的軟體,有一定的界面和必要的輔助功能。

那麼這個“計算核心”子產品和使用它的其他子產品之間是什麼關系呢? 它們要通過一定的API (Application Programming Interface) 來和其他子產品交流。 這個API 接口應該怎麼設計呢(有經驗和實力的童鞋可以考慮一下)? 為了簡單,我們可以從下面的最簡單的接口開始:

這個Calc 函數接受字元串的輸入(字元串裡就是運算式子,例如 “ 5+3.5“, “7/8 – 3/8 ”, “3 + 90 * (-0.3)“ 等等),這個子產品的傳回值是一個字元串,例如,前面幾個例子的結果就是 ( ”17.5“, “ 1/2”, “-24“).

假設我們用的是類,我們的測試程式剛開始可以是非常簡單的測試例子: (用僞代碼表示)

然後同學們實作自己 Core 的這個功能。

第一階段目标 - 能把計算的功能封裝起來,通過測試程式和API 接口測試其簡單的加法功能。

加法成功之後,然後我們再做減法, 乘法,除法,我們假設目前為止都是兩個操作數的運算,還是很容易實作的。 由于同學們已經在自己以前的程式中實作了各種算法,這時候隻要把實作的算法搬過來就好了。 大家可以不斷增加測試的數量,在每實作一個新的功能的時候,要保證以前運作正确的例子繼續是正确的, 通過這樣的 “回歸測試“, 來保證自己實作的函數一直是正确的。 (請看書中關于單元測試,回歸測試的内容)

第二階段目标 - 通過測試程式和API 接口測試其簡單的加減乘除功能。并能看到代碼覆寫率。

對于多個運算符的運算,帶負數的運算,我們這個子產品有一些參數要設定,例如,最多幾個運算符,資料範圍是多少,還要設定計算的精度(保留幾位小數,等等), 這是由什麼API 來決定呢? 我們可以擴充 Calc() 的定義,讓它接受一個新的參數 “precision”, 或者我們可以啟用一個新的函數 Setting()。如果我想表示:

最多4 個運算符

數值範圍是 -1000 到 1000

精度是小數點後兩位

怎麼通過API 告訴我們的子產品呢? 我們當然可以用函數的參數直接傳遞,但是參數的組合很多,怎麼定義好參數的規範呢? 建議大家考慮用 XML 來傳遞這些參數(實際就是在XML定義好規則,然後程式讀取XML規則來執行計算)。

增加了新的Setting() 函數之後,我們要讓子產品支援這樣的參數,同時,還要保證原來的各個測試用例繼續正确地工作。

第三階段目标 - 通過測試程式和API 接口測試對于各種參數的支援。并能看到代碼覆寫率。

這個時候,如果輸入是有錯誤的,例如 “1 ++ 2”, 在數值範圍是 -1000 .. 1000 的時候,傳進去 “10000 + 32768”, 或者是 “ 248 / 0” 怎麼辦? 怎麼告訴函數的調用者 “你錯了”? 把傳回的字元串定義為 “-1” 來表示? 那麼如果真的計算結果是 “-1” 又怎麼處理呢?

建議這個時候,我們要定義各種異常 (Exception), 讓 Core 在碰到各種異常情況的時候,能告訴調用者 - 你錯了! 當然,這個時候,我們同樣要進行下面的增量修改:

定義要增加什麼功能 - 例如:支援 “運算式子格式錯誤” 異常

寫好測試用例,傳進去一個錯誤的式子,期望能捕獲這個 異常。 如果沒有,那測試就報錯。

在 Core 子產品中實作這個功能

測試這個功能

同時測試所有以前的功能,保證以前的功能還能繼續工作 (沒有 regression)

确認功能完成,繼續下一個功能

第四階段目标 - 通過增量修改改程序式, 完成對各種錯誤情況的處理。

幾點說明:

時間:兩周(具體杜老師這邊安排) 每周完成兩個階段目标。

結對必須換一個隊友。

參考資料:

《建構之法》 單元測試,回歸測試内容

Java解析XML:http://inotgaoshou.iteye.com/blog/1012188

Junit教程:http://pan.baidu.com/s/1qWsaMVM

XML教程:http://pan.baidu.com/s/1s3u3c#path=%252F

Java自定義異常:http://blog.csdn.net/stellaah/article/details/6738424

繼續閱讀