Posted on 2007-01-25 00:03
laogao 閱讀(1379)
評論(1) 編輯 收藏 所屬分類:
On Java 、
Programming in General
作為開發者,我們必須要學會defensive programming,尤其是對要求高可靠性和無人職守的企業級應用中,需要特別留意我們的設計和編碼,必須盡可能做到足夠defensive。
什么是defensive programming?舉個大家都看過的例子:
String str = ...
if ("".equals(str)) {}
在這里我們不寫str.equals("")而是反過來,就是為了防止出現不必要的NPE – NullPointerException。
運行期異常是最最需要特別關照的一種非正常狀況,除了像上面這類要求我們采用相對較好的編碼習慣之外,為了減少運行期異常的發生,通常也需要使用try-catch代碼塊來把我們相對脆弱,或者需要格外保護的邏輯包起來,對于外部傳進來的參數,一定要assert它們的合法性,即assert它們是否能夠安全的被后面的邏輯所使用。
通常意義上,defensive programming主要cover的是避免不必要的運行期異常發生。我們可以更進一步,更廣義的運用defensive programming的核心思想:在企業應用中,除了運行期異常,對于有些看似嚴重的極端的錯誤,如網絡超時,連接丟失,數據庫提交失敗等情況,需要我們具體問題具體分析,并非所有checked exception都一定需要我們去一一catch然后處理。更多的時候,尤其當開發無人職守的后臺程序,我們可以采取重試、報告、修改外部數據等方式處理,能夠自行解決的,就不要動不動就報錯,或等待用戶確認,不能自行解決的,則要及時報告并停止運行,避免更大的錯誤發生。
舉個相對具體的例子,兩個異構的系統,通過一個中間層的消息平臺相互發送消息,通信協議采用最基本的socket方式,這三個系統隨時都可能出現宕機或鏈接中斷的情況。為了保證數據的完整性,我們拿其中一個需要發送和接收消息的系統來細說:
一個可能的實現方式是:該系統所有要發送的消息保存到數據庫,給它一個初始狀態;另一個獨立進程從數據庫按照時間先后拿出消息,更新拿出的這條消息的狀態為處理中,并嘗試發送消息;成功后根據需要,更新消息狀態為成功發送或者直接刪除,如果遇到失敗或異常,消息恢復為初始狀態,線程sleep一段時間,然后再次嘗試,多次嘗試或者嘗試跨度超過一定時間范圍,則停止處理,向管理員匯報(通過郵件、短信等途徑)。對于接收到的消息,同樣是先存入數據庫,然后再由后續的進程用類似的方式取出并處理。如果程序崩潰,可以自動重新啟動(應用或整個服務器)。這樣不管哪一段通信線路出現故障或阻塞,或者宕機,系統都可以一步一個腳印,確保任務主動而自動的執行,并且忠實記錄下有價值的狀態信息,出現問題時管理員可以很直觀的看到在哪個環節出現故障,從而快速找到問題關鍵并有效解決。
Defensive programming可以讓我們的應用更健壯,在保證數據正確性、完整性的前提下,面對困難也能更加獨立自主。和defensive programming相關的話題我想大家如果感興趣,可以展開更多更深入的探討,這里只是給大家做個介紹性的鋪墊,能拋磚引玉當然更好。