Re: [請益] BUG少的程式 通常有什麼特色?

看板Soft_Job作者 (喲)時間12年前 (2012/04/26 21:17), 編輯推噓8(8029)
留言37則, 7人參與, 最新討論串2/10 (看更多)
※ 引述《p52189 (皮爺)》之銘言: : 每次都要花很多時間在完工之後的測試和bug修正 : 甚至會有花在測試的時間比動手寫的時間還多的狀況!! : 我很想知道,bug少的程式究竟有些什麼樣的特質 : 而產出這些好程式的人,又是因為什麼樣的條件使他們手法漂亮? : 請各位前輩指點,也請盡量講得淺顯一點 : 感謝!!! 我回想一些經驗,覺得程式bug可以分為幾類: 1. 函數的值域及例外部份,變數的值域及例外部份,物件的行為及例外行為. 2. 資料算錯. 3. 機制錯誤,包括暫存資料沒有更新到前端. 第1類即包含了資料型態轉換問題,陣列超限問題,或是物件參考為空值,以及 小到除以0這樣的問題. 因為這些是很基本,很黑手的部份,處理方法就是邊寫程式 邊注意. 開始除錯也是以這個部份為主. 這個部份若bug少,程式的特質就是 都有很固定的慣例方式來避錯誤: 1a. 雜七雜八的關鍵值,都放到變數中: 例如for迴圈的邊界值n,函數的傳回值result. 1b. 固定的函數名稱和變數名稱: 例如取值getSomething..., 放值setSome..., 做一件事情doSome..., 判斷isSome... 1c. 函數盡可能壓到只有輸入參數和輸出,沒有從函數中參考到什麼外部變數. 1d. 對函數內容,變數值,物件行為的思考,是同時思考界內值域和界外值: 界內值該如何處理,應該很容易定義. 不過界外值或例外行為呢? 就要思考程式多需要這些界外或例外的資訊: 有些要藏,有些要let it be, 有些要跳出訊息,這些需要第一時間直接的細心. 1e. 程式功能做有效的分類. 1f. 用一些看起來沒必要但是有效的程式碼來保證程式正確: 例如,複製檔案, 然後刪除原檔,本來做法可能是: copy(fileName, anotherFileName); delete(fileName); 看起來好像蠻完美了. 但是有些工作經驗告訴我必須寫成: if (isExisting(fileName)) doCopy(fileName, anotherFileName); if (isExisting(anotherFileName) && isExisting(fileName)) doDelete(fileName); 普通來看,前面的判斷式在絕大部分時候很沒有必要. 可是,所謂避免bug 所要避的就是在比較罕見的時候,你要複製一個檔案但是找不到來源檔案, 或者你複製了檔案之後目標檔案不存在,以及要刪檔案的時候找不到檔案 等等這些運作上的狀況. (複製檔案之後目標會不存在嗎? 理論上不會,但實務上,會.) 第2類資料算錯的解決,因為是需要domain knowledge,以及需要參考需求定義,所以我 傾向於請使用者或測試人員幫忙提供夠多的資訊,使我能核對資料是否正確. 這個部份,我的感想是,如果需求沒辦法抓清楚,unit test有點難寫. 機制方面的偵錯,就比較是冒險了. 剛開始一定會試跑程式幾次,製造一些執行上的 狀態來確認軟體運作的行為是不是正確. 但是最後比較會是軟體交給使用者運行多次 之後,由使用者提醒有什麼樣怪怪的情況. 至於在事前預防的方式,我是用畫圖方式 將自己做好的軟體內容畫出來(UML)幫忙核對軟體的行為. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.112.229.204

04/26 22:08, , 1F
感謝!這一篇回覆非常仔細 1f我也曾碰到過 這一類的情況是
04/26 22:08, 1F

04/26 22:08, , 2F
否就需要依賴經驗呢?
04/26 22:08, 2F

04/26 22:13, , 3F
我覺得經驗告訴我,因為公司業務類型的需求,所以程式必須變這
04/26 22:13, 3F

04/26 22:14, , 4F
樣,比較算是腳本風格,並且程式累贅,格式生硬,幫助少動腦...
04/26 22:14, 4F

04/26 22:17, , 5F
甚至有一種少動腦,使產能穩定的方式是判斷式弄很簡單:
04/26 22:17, 5F

04/26 22:18, , 6F
if (isSomeSituation()){ }else { doSomething(); }
04/26 22:18, 6F

04/26 22:18, , 7F
這種寫法取代if(!isSomeSituation()){ doSomething(); }
04/26 22:18, 7F

04/26 22:29, , 8F
不懂前者好處是什麼?
04/26 22:29, 8F

04/26 22:44, , 9F
1f的兩個條件是不是寫反了?
04/26 22:44, 9F

04/26 22:57, , 10F
沒有,沒寫反. 第一個條件是要確定複製來源檔案確實存在,
04/26 22:57, 10F

04/26 22:57, , 11F
因為來源檔不在是鐵定失敗而造成程式錯誤的情況. 刪除舊檔
04/26 22:57, 11F

04/26 22:58, , 12F
的條件則是一要檔案已經複製出去,有備份不怕,二要要刪的檔案
04/26 22:58, 12F

04/26 22:58, , 13F
確實存在,以免試著刪不存在的檔案而造成程式錯誤.
04/26 22:58, 13F

04/26 23:02, , 14F
至於 if (isSomeSituation()){ }else { doSomething(); } 在
04/26 23:02, 14F

04/26 23:03, , 15F
有折行的情況,當你想要改條件說在那個狀態中要做什麼事,就
04/26 23:03, 15F

04/26 23:04, , 16F
貼進一行就可以. 至於判斷式是非常少有機會修改,而且閱讀時
04/26 23:04, 16F

04/26 23:05, , 17F
比較不用動腦. 我個人很愛拼複雜的判斷式,但是懂集合論的人
04/26 23:05, 17F

04/26 23:05, , 18F
實在不多. 那種寫法是我看到的lagacy code風格.
04/26 23:05, 18F

04/26 23:06, , 19F
legacy
04/26 23:06, 19F

04/27 00:39, , 20F
怎麼會有少機會修改就不用顧慮維護性呢...
04/27 00:39, 20F

04/27 00:40, , 21F
無論怎樣還是維護性高比較重要
04/27 00:40, 21F

04/27 06:56, , 22F
這樣寫的維護性很高,因為作法是將複雜的判斷式拉長為一連串
04/27 06:56, 22F

04/27 06:57, , 23F
等價的if-else系列. 留下的空間很方便用以行為本的方式增刪.
04/27 06:57, 23F

04/27 06:58, , 24F
而這種作法,我當然一點也不欣賞,只是順著目前方便配合而已.
04/27 06:58, 24F

04/27 09:43, , 25F
不好意思誤會y大了,請教能否給個例子參考看看呢?
04/27 09:43, 25F

04/27 09:46, , 26F
推yauhh,個人在一些案子裡面看過工程師真的是這樣做
04/27 09:46, 26F

04/27 09:47, , 27F
雖然不是很簡潔但概念相當清楚也好維護
04/27 09:47, 27F

04/27 11:36, , 28F
我是反而很推這樣雖然不簡潔但概念清楚也好維護的作法
04/27 11:36, 28F

04/27 11:36, , 29F
不過還是得看狀況, 看 case 的需要是如何而定
04/27 11:36, 29F

04/27 12:37, , 30F
我沒辦法給真的例子,因為程式都留在工作現場.
04/27 12:37, 30F

04/27 12:45, , 31F
不過,diablo你想要知道哪方面例子,我可以敲個sample給你看.
04/27 12:45, 31F

04/27 13:11, , 32F
"將複雜的判斷式拉長為一連串IF-ELSE"
04/27 13:11, 32F

04/27 13:12, , 33F
想知道這句話的例子,麻煩了~
04/27 13:12, 33F
基本型: 不使用 not (!)運算,所以 if ( !a ) { b(); } 要寫成 if ( a ) { } else { b(); } 複雜式化簡: 以下這樣若要反轉判斷式,邏輯技巧是笛摩根定律 if ( a || b ) { => if ( !a && !b ) { c(); c_(); } } 不要用稍微複雜的判斷式,所以原程式寫成: if ( a ) { c(); } else if ( b ) { c(); } 要反轉的時候就是改成: if ( a ) { //c(); } else if ( b ) { //c(); } else { c_(); } ※ 編輯: yauhh 來自: 59.112.224.243 (04/27 13:37)

04/27 16:19, , 34F
感謝!以前都沒接觸過
04/27 16:19, 34F

04/27 16:20, , 35F
我都是直接寫在一起...
04/27 16:20, 35F

04/27 20:49, , 36F
原來!
04/27 20:49, 36F

04/28 10:50, , 37F
04/28 10:50, 37F
文章代碼(AID): #1FcKhf5G (Soft_Job)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 10 篇):
文章代碼(AID): #1FcKhf5G (Soft_Job)