隨筆 - 17  文章 - 49  trackbacks - 0
          <2006年9月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          常用鏈接

          留言簿(1)

          隨筆分類(17)

          隨筆檔案(17)

          相冊

          最新隨筆

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          2006 929 星期五

          檢查方法參數,平凡處的學問

          -effective java item 23


          ????大多數方法和構造器都對參數有一定的限制要求,然而有否顯式地檢查參數就因人而異,回想自己的編碼歷程,也常在興沖沖之際,直接奔向業(yè)務邏輯。然而這個看似平凡的小地方,卻應該養(yǎng)成一個堅固的習慣,小小付出帶來的效果事實上相當可觀。

          若有非法的參數傳入,加以檢查,則會立刻引發(fā)意義明確的異常。相反,若無此檢查,后續(xù)情形大相徑庭。該方法可能在某一行猝死,死因報告相當迷離;更劣者,方法最后壽終正寢,返回的卻是錯誤的計算結果;最劣者,順利走完并返回正確的結果,但執(zhí)行的過程某些牽涉到的對象被設置成不正確的狀態(tài),這些隱患最后爆發(fā)于無法預計的時刻和地點。

          因而,檢查參數的正確性這一舉動帶來的貢獻,更多的是來源于這一舉動若不存在時可能帶來的麻煩,這扇大門過于開放,則帶來日后清理門戶時過多的周折。

          除去檢查需要進行計算的參數,更要注意檢查在本方法中并未使用但存儲起來以備后用的參數,若不加檢查,等到異常發(fā)生的時候,來源難以追蹤。大大增加了debug的痛苦,這一點,想必很多coder會有這樣的郁悶回憶。構造方法是這種情形的典型,構造器的大多數參數是屬于這種“以備后用”的類型。錯誤的參數可能導致類的邏輯規(guī)則被破壞,此后導致的異常可能非常奇怪而且難以理清緣由。

          凡事必有例外。某些情形下,參數檢查是不應該執(zhí)行的,例如這種檢查代價昂貴或者不切實際,而且,(注意,是而且)合法性的檢查在計算的過程中隱式的進行。例如一個對list里的object進行排序的方法,這些object必須是相互可比較的,否則,比較過程中就會拋出ClassCastException,這也正是排序方法應該拋出的異常,因而事先進行可比性的檢查就無意義了。但如果不謹慎的使用這種隱式檢查的技巧,就會損失錯誤的原子性,比如這個方法不僅僅是比較,而且還進行寫操作,那么中途拋出異常的時候,已經有某些數據被改動了,你不得不進行roll back,否則就要接受一個半成品。這一方面在item 46里有更多的描述。另外,有時候這種隱式的檢查所拋出的異常,也可能并非真正的病因,你還需要做些異常的“翻譯”來指引真實的問題根源。

          以上所說并非鼓勵你限制參數,事實上,只要方法本身能應付得來,就應該盡量放寬參數的限制,方法才能有通用性。

          總而言之,每當你寫一個方法或構造器,就應該考慮會有什么限制需要加之于參數上,為此配上文檔說明,在方法一開始就顯式檢查,養(yǎng)成這樣的習慣很重要,這一點點謹慎的工作,在這個方法第一次拋出參數異常的時候,就開始了對你的回報。


          Friday, September 29, 2006

          Check method parameters for validity, knowledge within a trivial spot

          ???? -effective java item 23

          ?

          Most of methods and constructors have constraints on their parameters, but whether carry out a validity check differs from people to people. Recalling my own programming experience, I did rush to implement the business without making a check. But rigid habit shall be kept here, the little effort really brings back a lot.

          If an invalid parameter is passed into a method with checking, a prompt and clear exception will be thrown, the situation can be quite different without a check. The method may fail somewhere on the way, reporting a confusing exception or error; to be worse, the method executed successfully, but giving back a wrong result, and the worst one, the method end with a correct result, but corrupted some relevant objects during the process, and these latent problems will break out somewhere or sometime you never know.

          Therefore, the benefits of checking for validity actually comes from the fact that possibly lots of problems will appear without the checking. The door was too open and brings too much threat to future situation.

          Besides checking parameters for calculation, more attention shall be put on the checking on parameters that are stored for later use. Without the checking, errors will occur sometime when the original instances are difficult to trace, which brings miserable experience to the debugging process. I supposed quite a lot of coders had tasted that. Constructors are a representative case, most of the parameters of constructors are for later uses, invalid parameters will violate invariants of the class, the exception it caused can be very weird and hard to solve.

          There is exception. In some case which validity checking is expensive or impractical and the check can be perform implicitly in the process of calculation. For instance, a method sorting a list, for such a method, the objects in the list must be mutually comparable, otherwise a ClassCastException will be thrown, and it is exactly the exception a sorting methods should throws, so it will be meaningless to check them ahead of time. However, indiscriminate application of such techniques can lead to the loss of failure atomicity. For example, the method does more than sorting, it also do some writing operation of the objects, in such case, by the time an exception is thrown, some of the objects have already been modified, you have to roll back, or, accept a half complete result. This is discussed in detail in item 46. What’s more, sometimes exception thrown by implicit check can not tell the really problems, and you have to do some “exception translating” for revealing the real cause.

          The above information does not means that arbitrary restrictions on parameters are a good thing. In fact, you shall put fewer restrictions on them as long as the method is capable of dealing the parameters. By this way we get more general methods.

          To summarize, you shall consider what restrictions should exist on the parameters when you are writing a method or constructor, and document for them, apply explicit check in the beginning of the method body, it is important to get into the habit of doing this, this modest work will start pay back at the first time a validity check fails.

          posted on 2006-09-29 13:36 Ye Yiliang 閱讀(1502) 評論(1)  編輯  收藏 所屬分類: Java

          FeedBack:
          # re: 檢查方法參數,平凡處的學問 2006-09-30 11:27 hsp
          不同場合,對調用者的信任程度不同~
          存在一種思想是,由調用者確保參數的正確性,當然這在某種場合下適用.
          例如inbound  回復  更多評論
            
          主站蜘蛛池模板: 闽侯县| 开原市| 上思县| 武陟县| 大庆市| 长寿区| 古交市| 抚松县| 安达市| 屏南县| 安泽县| 大港区| 洛隆县| 濮阳县| 湖口县| 通州区| 黎平县| 方正县| 佳木斯市| 平遥县| 类乌齐县| 盈江县| 宿迁市| 雷州市| 白河县| 漠河县| 河南省| 岳池县| 房产| 壶关县| 淮安市| 唐河县| 博乐市| 苏尼特左旗| 洪雅县| 汨罗市| 昌邑市| 西乌珠穆沁旗| 平武县| 黎川县| 鸡东县|