Posted on 2005-12-10 14:17
小李飛刀 閱讀(266)
評論(0) 編輯 收藏
老話題了,自己收集總結(jié)了一下
代碼調(diào)試排錯通常是一個痛苦的過程,至少我是這么認為的:-)。對開發(fā)人員而言,其實可以在設(shè)計和編碼時期加以控制,以提高代碼質(zhì)量,
減少后期工作壓力。
下面粗略列舉一些應(yīng)該注意的問題,詳細內(nèi)容建議參考JTest的規(guī)則,以及DBC -- Design By Contract 規(guī)則。
JAVA設(shè)計和編碼過程中應(yīng)該注意的幾個問題:
1. 不要把問題推遲到運行時刻,盡可能地在編譯時暴露問題
這是個原則性問題,對所有的語言都是一樣的,強類型語言的出現(xiàn)就是這個原則的一個體現(xiàn)。
a. 如果某個方法需要拋出異常,在方法的定義中就讓它拋出,利于編譯時檢查,否則調(diào)用者如果忘記捕獲異常,編譯時也不會得到提示,
錯誤將延遲到運行時刻,難以調(diào)試處理。
b. 形參的存取控制,如果不希望在方法中改變參數(shù)所引用的對象,可以用final對該參數(shù)進行限制,這樣編譯器就會幫你檢查。(其實Java
中對參數(shù)加上final修飾并沒有什么實際用處,因為JAVA使用passed by value方式來傳遞參數(shù),因此切記不要期望在方法內(nèi)對參數(shù)賦值能
使調(diào)用者獲得新的對象)。
c. 避免含義模糊的參數(shù),盡量不要為了方便而使用像Hashtable,Vector這樣含義模糊的集合類(Collection)參數(shù)來傳遞對象,除非在不
得已的情況下才使用,但一般而言,使用抽象類的數(shù)組,以及通過良好的類層次結(jié)構(gòu)設(shè)計是可以做到避免集合(Collection)類的使用的。
凡事總有例外,一些模式例如工廠模式有時候需要折衷處理這個問題,為了框架代碼不至于因為子類的增加而被頻繁修改,有時候不得不把
問題延遲到運行時刻處理。
2. 盡可能地在一個方法中只做一件事,如果方法實在比較復(fù)雜,盡量把它分割成合適的幾個輔助方法, 內(nèi)聚和耦合的原則同樣適用于小方法
的設(shè)計,大架構(gòu),小方法可以帶給程序更好的可維護性和可測試性,同時也可以提供更多的可復(fù)用代碼,如果系統(tǒng)結(jié)構(gòu)需要調(diào)整時,這一優(yōu)勢
將會非常明顯,復(fù)雜的方法和糾纏不清的邏輯除了扔掉重來外別無它法。
方法定義應(yīng)該言行一致,方法名稱就應(yīng)該完全說明這個方法是干什么的。
3. 接口或方法的存取控制問題,接口應(yīng)該盡可能地簡單,不必讓調(diào)用者知道的方法,應(yīng)該用private修飾符;提供給子類繼承的用
protected修飾,只有需要提供給外部調(diào)用的方法才允許用public,默認為包內(nèi)可見但最好少用.
4. 屬性的存取控制,原則上講,除了接口的常量定義外,一般不允許使用public修飾,需要提供給子類控制的用protected,其他用
private,特別注明,默認為包內(nèi)可見(有點類似C++的friendly),盡可能明確標記其訪問權(quán)限,不要含糊地使用大的范圍。
5. 使用接口還是類來定義常量, 原則上是盡量使用接口,這樣可以減少運行時的內(nèi)存使用,運行時JVM可能也少耗費資源(需要確認),
至少一個可信的理由就是JDK提供的一些內(nèi)部使用的常量定義都是在接口中定義的:-)。interface中的成員和方法默認都是public, JTest
規(guī)則中對在Interface中的定義加public修飾符會報錯,個人覺得沒有必要,應(yīng)該明確標記比較好。
6. 出錯時或重要邏輯點打印出盡可能詳細的信息,包括當前操作信息,一些參量的值,最好還有代碼的位置信息,很多問題難以重現(xiàn),及時
捕捉并打印出詳細的調(diào)試信息有助于盡快解決故障。
7. 分開處理和集中控制的折衷, 雖然應(yīng)該盡可能地按照事務(wù)或業(yè)務(wù)的需要分開處理,但對一些用來調(diào)整和控制整個系統(tǒng)的定義量最好集中
控制,系統(tǒng)的性能方面應(yīng)該盡可能做到可調(diào)整的(tunable).
8. 代碼重構(gòu) 代碼重構(gòu)是一個漸進的,永遠的過程,只要代碼的生命還沒有結(jié)束,就需要不斷的改進,逐步地提煉出公用的東西,將基礎(chǔ)支持
部分從應(yīng)用中剝離出來同時就是在準備下一個應(yīng)用的開發(fā);代碼結(jié)構(gòu)和邏輯逐步變得更加清晰,可維護性和可測試性也在逐步提高,更重要的是
代碼改進的同時,開發(fā)人員也在同步改進和提高。
9. Self-documented Coding 盡量在代碼中用注釋說明當前代碼的處理邏輯和一些應(yīng)該注意的問題,特別是一些特殊的處理細節(jié),除了注釋外
軟件產(chǎn)品的其他地方似乎沒有合適的位置保存這類信息。
10. Self-test 代碼,比較重要的單元自測代碼跟被測試代碼保存在一起比較合適,避免代碼間關(guān)系復(fù)雜化,保持單元間的獨立性
11. 盡可能少地生成對象,特別是大對象; 雖然硬件速度的提高能夠加快Java代碼的執(zhí)行,但過多的使用內(nèi)存使得Java程序普遍較慢,并且
經(jīng)常使得系統(tǒng)無法同時運行其他任務(wù)。 String類使用方便,但是頻繁使用拼接( + )操作會帶來很多的臨時String對象,需要多次拼接形成
String時,應(yīng)該考慮用StringBuffer.append()方法代替。對大系統(tǒng)而言,應(yīng)該有可調(diào)整的策略來干預(yù)控制垃圾回收。
12. 盡可能地減少嵌套類和內(nèi)部類的使用,杜絕局部類的使用,匿名類只用于監(jiān)聽器(XXXListener)。
13. 不要使用太多的參數(shù),可以考慮用一個類來封裝參數(shù),但參數(shù)類也不能難以構(gòu)造,如果出現(xiàn)這種問題,建議重新考慮設(shè)計是否合理。
14. 命名,盡量使用有意義的名稱來定義成員變量,方法名,常量,方法參數(shù)名稱也非常重要。
15. 文檔, JavaDoc文檔應(yīng)該盡量清楚,對于提供給開發(fā)人員使用的庫,其對應(yīng)JavaDoc應(yīng)該詳細到開發(fā)時在集成工具中使用而不必再參考其
他文檔的程度,具體包括方法的目的,出參、入?yún)⒌南拗啤⒆兓约皩︻惖臓顟B(tài)的影響,參見DBC的@pre 和@post條件。