樂在其中

          以JEE為主攻,以Flex為點綴,以Eclipse RCP為樂趣
          請訪問http://www.inframesh.org

          首頁 新隨筆 聯(lián)系 管理
            43 Posts :: 0 Stories :: 8 Comments :: 0 Trackbacks

          1 基本信息

          摘要:本文倡導(dǎo)一種對異常條件本質(zhì)的思考方式,并描述一些有助于設(shè)計的模式。最后,本文還將在AOP模型中,作為相互滲透的問題,來討論異常的處理。當(dāng)你能正確使用異常時,它們會有極大的好處。本文將幫助你做到這一點。

          原作者:Barry Ruzek   譯者: 易曉斕,原文:http://www.yeeyan.com/articles/view/2091/976

          2 為何異常是如此重要

            Java應(yīng)用中的異常處理在很大程度上揭示了其所基于架構(gòu)的強度。架構(gòu)是在應(yīng)用程序各個層次上所做出并遵循的決定。其中最重要的一個就是決定應(yīng)用程序中的類,亞系統(tǒng),或?qū)又g溝通的方式。Java異常是Java方法將另類執(zhí)行結(jié)果交流出去的方式,所以值得在應(yīng)用架構(gòu)中給予特殊關(guān)注。

            一個衡量Java設(shè)計師水平和開發(fā)團隊紀(jì)律性的好方法就是讀讀他們應(yīng)用程序里的異常處理代碼。首先要注意的是有多少代碼用于捕獲異常,寫進日志文件,決定發(fā)生了什么,和在不同的異常間跳轉(zhuǎn)。干凈,簡捷,關(guān)聯(lián)性強的異常處理通常表明開發(fā)團隊有著穩(wěn)定的使用Java異常的方式。當(dāng)異常處理代碼的數(shù)量甚至要超過其他代碼時,你可以看出團隊之間的交流合作有很大的問題(可能在一開始就不存在),每個人都在用他們自己的方式來處理異常。

            對突發(fā)異常的處理結(jié)果是可以預(yù)見的。如果你問問團隊成員為什么異常會被拋出,捕獲,或在特定的一處代碼里忽視了異常的發(fā)生,他們的回答通常是,“我沒有別的可做”。如果你問當(dāng)他們編寫的異常真的發(fā)生了會怎么樣,他們會皺皺眉,你得到的回答類似于這樣,“我不知道。我們從沒測試過。”

            你可以從客戶端的代碼判斷一個java的組件是否有效利用了java的異常。如果它們包含著大堆的邏輯去弄清楚在何時一筆操作失敗了,為何失敗,是否有彌補的余地,那么原因很有可能要歸咎于組件的報錯設(shè)計。錯誤的報錯系統(tǒng)會在客戶端產(chǎn)生大量的“記錄然后忘掉”的代碼,這些代碼鮮有用途。最差的是弄擰的邏輯,嵌套的try/catch/finally代碼塊,和一些其他的混亂而導(dǎo)致脆弱而難于管理的應(yīng)用程序。

            事后再來解決Java異常的問題,或根本就不解決,是軟件項目產(chǎn)生混亂并導(dǎo)致滯后的主要原因。異常處理是一個在設(shè)計的各個部分都急需解決的問題。對異常處理建立一個架構(gòu)性的約定是項目中首要做出的決定。合理使用Java異常模型對確保你的應(yīng)用簡單,易維護,和正確有著長遠(yuǎn)的影響。

          3 解析異常

            正確使用Java異常模型所包含的內(nèi)容一直以來有著很大的爭議。Java不是第一種支持異常算法語義的;但是,它卻是第一種通過編譯器來執(zhí)行聲明和處理某些異常的規(guī)則的語言。許多人都認(rèn)為編譯時的異常檢查對精確的軟件設(shè)計頗有幫助。圖1顯示的Java異常的等級。
           

          圖1:Java異常的等級

            通常,Java編譯器強迫拋出基于java.lang.Throwable的異常的方法要在它聲明中的“throws”部分加上那個異常。而且,編譯器還會證實客戶端的方法或者捕獲已聲明的異常,或者特別聲明自己也拋出同樣的異常。這些簡單的規(guī)則對世界范圍的Java程序員都有深遠(yuǎn)的影響。

            編譯器放松了對Throwable繼承樹中兩個分支的異常檢查。java.long.Error和java.lang.RuntimeException 的子類免于編譯時的檢查。在這兩類中,軟件工程師通常對運行中異常更感興趣。“不檢查”的異常指的是這一組,以便和所有其它“檢查”的異常區(qū)別開。

            我可以想象那些接受“檢查”的異常的人,也會很看重Java的數(shù)據(jù)類型。畢竟,編譯器對數(shù)據(jù)類型施加的限制鼓勵嚴(yán)格的編碼和精確的思維。編譯時的類型檢查對減少運行時的嚴(yán)重問題有幫助。編譯時的異常檢查也能起到類似的作用,它會提醒開發(fā)人員某個方法可能會有預(yù)想不到的結(jié)果需要處理好。

            早期的建議是盡可能的使用“檢察的異常”,以此來最大限度的利用編譯器提供的幫助來寫出無錯誤的軟件。Java類庫API的設(shè)計者們都認(rèn)同這一點,他們廣泛地使用“檢察的異常”來模擬類庫方法中幾乎所有的緊急應(yīng)變措施。在J2SE5.1 API規(guī)格中,“檢察的異常”類型已2比1的比率超過了“未檢查的異常”類型。

            對程序員而言,看上去在Java類庫中大多數(shù)的常用方法對每一個可能的失敗都聲明了“檢察的異常”。例如,java.io包
          對IOException這個“檢察的異常”就有著很大的依賴。至少有63個Java類庫包,或直接,或通過十幾個下面的子類,拋出這個異常。

            I/O的失敗極其稀有,但是卻很嚴(yán)重。而且,一旦發(fā)生,從你所寫的代碼里基本上是無法補救的。Java程序員意識到他們不得不提供IOException 或類似的不可補救的事件,而一個簡單的Java類庫方法的調(diào)用就可能讓這些事件發(fā)生。捕獲這些異常給本來簡單的代碼帶來了一定的晦澀,因為即使在捕獲的代碼塊里也基本上幫不上忙。但是不加以捕獲又可能更糟糕,因為編譯器要求你的方法必須要拋出那些異常。這樣你的實施細(xì)則就不得不暴露在外了,而通常好的面向?qū)ο蟮脑O(shè)計都是要隱藏細(xì)節(jié)的。

            這樣一個不可能贏的局面導(dǎo)致了我們今天所警告的絕大多數(shù)臭名卓著的異常處理的顛覆性格局。同時也衍生了很多正確或錯誤的補救之道。

            一些Java界的知名人物開始質(zhì)疑Java的“檢察的異常”的模型是否是一個失敗的試驗。有一些東西肯定是失敗的,但是這和在Java語言里加入對異常的檢查是毫無關(guān)聯(lián)的。失敗是由于在Java API的設(shè)計者們的思維里,大多數(shù)失敗的情形是雷同的,所以可以通過同一種異常傳達(dá)出去。

          4 故障和應(yīng)變

            讓我們來考慮在一個假想的銀行應(yīng)用中的CheckingAccount類。一個CheckingAcccount屬于一個用戶,記載著用戶的存款余額,也能接受存款,接受止兌的通知,和處理匯入的支票。一個CheckingAcccount對象必須協(xié)調(diào)同步線程的訪問,因為任何一個線程都可能改變它的狀態(tài)。CheckingAcccount類里processCheck的方法會接受一個Check對象為參數(shù),通常從帳戶余額里減去支票的金額。但是一個管理支票清算的用戶端程序調(diào)用processCheck方法時,必須有兩種可能的應(yīng)變措施。一,CheckingAccount對象里可能對該支票已有一個止付的命令;二,帳戶的余額可能不足已滿足支票的金額。

            所以,processCheck的方法對來自客戶端的調(diào)用可以有3種方式回應(yīng)。正常的是處理好支票,并把方法簽名里聲明的結(jié)果返回給調(diào)用方。兩種應(yīng)變的回應(yīng)則是需要與支票清算端溝通的在銀行領(lǐng)域?qū)崒嵲谠诖嬖诘那闆r。processCheck方法所有3種返回結(jié)果都是按照典型的銀行支票帳戶的行為而精心設(shè)計的。

            在Java里,一個自然的方法來表示上述緊急的應(yīng)變是定義兩種異常,比如StopPaymentException(止付異常)和 InsufficientFundsException(余額不足異常)。一個客戶端如果忽略這些異常是不對的,因為這些異常在正常操作的情況下一定會被拋出。他們?nèi)缤椒ǖ暮灻粯臃从沉朔椒ǖ娜嫘袨椤?/font>

            客戶端可以很容易的處理好這兩種異常。如果對支票的兌付被停止了,客戶端把該支票交付特別處理。如果是因為資金不足,用戶端可以從用戶的儲蓄帳戶里轉(zhuǎn)移一些資金到支票帳戶里,然后再試一次。

            在使用CheckingAccount的API時,這些應(yīng)變都是可以預(yù)計的和自然的結(jié)果。他們并不是意味著軟件或運行環(huán)境的失敗。這些異常和由于CheckingAccount類中一些內(nèi)部實施細(xì)則引起的真正失敗是不同的。

            設(shè)想CheckingAccount對象在數(shù)據(jù)庫里保持著一個恒定的狀態(tài),并使用JDBC API來對之訪問。在那個API里,幾乎所有的數(shù)據(jù)庫訪問方法都有可能因為和CheckingAccount實施無關(guān)的原因而失敗。比如,有人可能忘了把數(shù)據(jù)庫服務(wù)器運行起來,一個未有連上的網(wǎng)絡(luò)數(shù)據(jù)線,訪問數(shù)據(jù)庫的密碼改變了,等等。

            JDBC依靠一種“檢查的異常”,SQLException,來匯報任何可能的錯誤。可能出錯的絕大多數(shù)原由都是數(shù)據(jù)庫的配置,連接,或其所在的硬件設(shè)施。對processCheck方法而言,它對上述錯誤是無計可施的。這不應(yīng)該,因為processCheck至少了解它自己的實施細(xì)則。在調(diào)用棧里上游的方法能處理這些問題的可能就更小。

            CheckingAccount這個例子說明了一個方法不能成功返回它想要的結(jié)果的兩個基本原因。這里是兩個描述性的術(shù)語:

          應(yīng)變
              與實際預(yù)料相符,一個方法給出另外一種回應(yīng),而這種回應(yīng)可以表達(dá)成該方法所要達(dá)到的目的之一。這個方法的調(diào)用者預(yù)料到這個情況的出現(xiàn),并有相對的應(yīng)付之道。

          故障
              在未經(jīng)計劃的情況下,一個方法不能達(dá)到它的初衷,這是一個不訴諸該方法的實施細(xì)則就很難搞清的情況。
              應(yīng)用這些術(shù)語,對processCheck方法而言,一個止付的命令和一個超額的提取是兩種可能的應(yīng)變。而SQLException反映了可能的故障。processCheck方法的調(diào)用者應(yīng)該能夠提供應(yīng)變,但卻不一定能有效的處理好可能發(fā)生的故障。

          Java異常的匹配
              在建立應(yīng)用架構(gòu)中Java異常的規(guī)則時,以應(yīng)變和故障的方式仔細(xì)考慮好“什么可能會出錯”是有長遠(yuǎn)意義的。

            應(yīng)變情況恰如其分地匹配給了Java檢查的異常。因為它們是方法的語義算法合同中不可缺少的一部分,在這里借助于編譯器的幫助來確保它們得到解決是很有道理的。如果你發(fā)現(xiàn)編譯器堅持應(yīng)變的異常必須要處理或者在不方便的時候必須要聲明會給你帶來些麻煩,你在設(shè)計上幾乎肯定要做些重構(gòu)了。這其實是件好事。

            出現(xiàn)故障的情況對開發(fā)人員而言是蠻有意思的,但對軟件邏輯而言卻并非如此。那些軟件”消化問題“的專家們需要關(guān)于故障的信息以便來解決問題。因此,未檢查的異常是表示故障的很好方式。他們讓故障的通知原封不動地從調(diào)用棧上所有的方法濾過,到達(dá)一個專門來捕獲它們的地方,并得到它們自身包含的有利于診斷的信息,對整個事件提供一個有節(jié)制的優(yōu)雅的結(jié)論。產(chǎn)生故障的方法不需要來聲明(異常),上游的調(diào)用方法不需要捕獲它們,方法的實施細(xì)則被正確的隱藏起來- 以最低的代碼復(fù)雜度。

            新一些的Java API,比如像Spring架構(gòu)和Java Data Ojects類庫對檢查的異常幾乎沒有依賴。Hibernate ORM架構(gòu)在3.0版本里重新定義了一些關(guān)鍵功能來去除對檢查的異常的使用。這就意味著在這些架構(gòu)舉報的絕大部分異常都是不可恢復(fù)的,歸咎于錯誤的方法調(diào)用代碼,或是類似于數(shù)據(jù)庫服務(wù)器之類的底層部件的失敗。特別的,強迫一個調(diào)用方來捕獲或聲明這些異常幾乎沒有任何好處。
          設(shè)計里的故障處理

            在你的計劃里,承認(rèn)你需要去做就邁好了有效處理好故障的第一步。對那些堅信自己能寫出無懈可擊的軟件的工程師們來說,承認(rèn)這一點是不容易的。這里是一些有幫助的思考方式。首先,如果錯誤俯拾即是,應(yīng)用的開發(fā)時間將很長,當(dāng)然前提是程序員自己的bug自己修理。第二,在Java類庫中,過度使用檢查的異常來處理故障情形將迫使你的代碼要應(yīng)對好故障,即使你的調(diào)用次序完全正確。如果沒有一個故障處理的架構(gòu),湊合的異常處理將導(dǎo)致應(yīng)用中的信息丟失。

          一個成功的故障處理架構(gòu)一定要達(dá)到下面的目標(biāo):
          • 減少代碼的復(fù)雜性
          • 捕獲和保存診斷性信息
          • 對合適的人提醒注意
          • 優(yōu)雅地退出行動

            故障是應(yīng)用的真實意圖的干擾。因此,用來處理它們的代碼應(yīng)盡量的少,理想上,把它們和應(yīng)用的語義算法部分隔離開。故障的處理必須滿足那些負(fù)責(zé)改正它們的人的需要。開發(fā)人員需要知道故障發(fā)生了,并得到能幫助他們搞清為何發(fā)生的信息。即使一個故障,在定義上而言,是不可補救的,好的故障處理會試著優(yōu)雅地結(jié)束引起故障的活動。

          對故障情況使用未檢查的異常

            在做框架上的決定時,用未檢查的異常來代表故障情況是有很多原因的。Java的運行環(huán)境對代碼的錯誤會拋出“運行時異常”的子類,比如, ArithmeticException或ClassCastException。這為你的框架設(shè)了一個先例。未檢查的異常讓上游的調(diào)用方法不需要為和它們目的不相關(guān)的情況而添加代碼,從而減少了混亂。

            你的故障處理策略應(yīng)該認(rèn)識到Java類庫的方法和其他API可能會使用檢查的異常來代表對你的應(yīng)用而言只可能是故障的情況。在這種情形下,采用設(shè)計約定來捕獲API異常,將其以故障來看待,拋出一個未檢查的異常來指示故障的情況和捕獲診斷的信息。

            在這種情況下拋出的特定異常類型應(yīng)該由你的框架來定義。不要忘記一個故障異常的主要目的是傳遞記錄下來的診斷信息,以便讓人們來想出出錯的原因。使用多個故障異常類型可能有些過,因為你的架構(gòu)對它們都一視同仁。多數(shù)情況下,一條好的,描述性強的信息將單一的故障類型嵌入就夠用了。使用Java基本的 RuntimeException來代表故障情況是很容易的。截止到Java1.4,RuntimeException,和其他的拋出類型一樣,都支持異常的嵌套,這樣你就可以捕獲和報出導(dǎo)向故障的檢查的異常。

            你也許會為了故障報告的目的而定義你自己的未檢查的異常。這樣做可能是必要的,如果你使用Java1.3或更早的版本,它們都不支持異常的嵌套。實施一個類似的嵌套功能來捕獲和轉(zhuǎn)換你應(yīng)用中構(gòu)成故障的檢查的異常是很簡單的。你的應(yīng)用在報錯時可能需要一個特殊的行為。這可能是你在架構(gòu)中創(chuàng)建 RuntimeException子類的另一個原因。

          建立一個故障的屏障

            對你的故障處理架構(gòu)而言,決定拋出什么樣的異常,何時拋出是重要的決定。同樣重要的是,何時來捕獲一個故障異常,之后再怎么辦。這里的目的是讓你應(yīng)用中的功能性部分不需要處理故障。把問題分開來處理通常都是一件好事情,有一個中央故障處理機制長遠(yuǎn)來看是很有裨益的。

            在故障屏障的模式里,任何應(yīng)用組件都可以拋出故障異常,但是只有作為“故障屏障”的組件才捕獲異常。采用此種模式去除了大多數(shù)程序員為了在本地處理故障而插入的復(fù)雜的代碼。故障屏障邏輯上位于調(diào)用棧的上層,這樣在一個默認(rèn)的行動被激發(fā)前,一個異常向上舉報的行為就被阻止了。根據(jù)不同的應(yīng)用類型,默認(rèn)的行動所指也不同。對一個獨立的Java應(yīng)用而言,這個行動指活著的線程被停止。對一個位于應(yīng)用服務(wù)器上的Web應(yīng)用而言,這個行動指應(yīng)用服務(wù)器向瀏覽器送出不友好的(甚至令人尷尬的)回應(yīng)。

            一個故障屏障組件的第一要務(wù)就是記錄下故障異常中包含的信息以為將來所用。到現(xiàn)在為止,一個應(yīng)用日志是做成此事的首選。異常的嵌套的信息,棧日志,等等,都是對診斷有價值的信息。傳遞故障信息最差的地方是通過用戶界面。把應(yīng)用的使用者卷進查錯的進程對你,對你的用戶而言都不好。如果你真的很想把診斷信息放上用戶界面,那可能意味著你的日志策略需要改進。

            故障屏障的下一個要務(wù)是以一種可控的方式來結(jié)束操作。這具體的意義要取決于你應(yīng)用的設(shè)計,但通常包括產(chǎn)生一個可通用的回應(yīng)給可能正在等待的客戶端。如果你的應(yīng)用是一個Web service,這就意味著在回應(yīng)中用soap:Server的<faultcode>和通用的失敗信息< faultstring>來建立一個SOAP故障元素<fault>。如果你的應(yīng)用于瀏覽器交流,這個屏障就會安排好一個通用的 HTML回應(yīng)來表明需求是不能被處理的。

            在一個Struts的應(yīng)用里,你的故障屏障會以一種全局異常處理器的形式出現(xiàn),并被配置成處理RuntimeException的任何子類。你的故障屏障類將延伸org.apache.struts.action.ExceptionHandler類,必要的話,重寫它的方法來實施用戶自己的特別處理。這樣就會處理好不小心產(chǎn)生的故障情況和在處理一個Struts動作時發(fā)現(xiàn)的故障。圖2顯示的就是應(yīng)變和故障異常。
           

          圖2 應(yīng)變和故障異常

            如果你使用的是Spring MVC架構(gòu),你可以繼承SimpleMappingExceptionResolver類,并配置成處理RuntimeException和它的子類們,這樣很容易的就建起了故障屏障。通過重寫resolveException的方法,你可以在使用父類的方法來把需求導(dǎo)引到一個發(fā)出通用錯誤提示的view 組件之前,加入你需要的用戶化的處理。

            當(dāng)你的架構(gòu)包含了故障屏障,程序員都知曉了后,再寫出一次性的故障異常的沖動就會銳減。結(jié)果就是應(yīng)用中出現(xiàn)更干凈,更易于維護的代碼。

          5 架構(gòu)中應(yīng)變的處理

            將故障處理交與屏障后,主要組件間的應(yīng)變交流變得容易多了。一個應(yīng)變代表著與主要返回結(jié)果同等重要的另外一種方法結(jié)果。因此,檢查的異常類型是一個能夠很好地傳遞應(yīng)變情況的存在并提供必要的信息來與它競爭的工具。這個方式借助于Java編譯器的幫助來提醒程序員關(guān)于他們所用的API的方方面面以及提供全套的方法輸出的必要性。

            僅僅使用方法的返回值類型來傳遞簡單的應(yīng)變是可能的。比如,返回一個空引用,而不是一個具體的對象,可以意味著對象由于一個已定義的原因不能被建立。 Java I/O的方法通常返回一個整數(shù)值-1,而不是字節(jié)的值或字節(jié)的數(shù)來表示文件的結(jié)尾。如果你的方法的語義簡單到可以允許的地步,另一種返回值的方法是可以使用的,因為它摒棄了異常帶來的額外的花銷。不足之處是方法的調(diào)用方要檢測一下返回的值來判斷是主要結(jié)果,還是應(yīng)變結(jié)果。但是,編譯器沒有辦法來保證方法調(diào)用者會使用這個判斷。

            如果一個方法有一個void的返回類型,異常是唯一的方法來表示應(yīng)變發(fā)生了。如果一個方法返回的是一個對象的引用,那么返回值只可能是空或非空(null and non-null)。如果一個方法返回一個整數(shù)型,選擇與主要返回值不沖突的,可以表示多種應(yīng)變情況的數(shù)值是可能的。但是這樣的話,我們就進入了錯誤代碼檢查的世界,而這正式Java異常模式所著力避免的。
          提供一些有用的信息

            定義不同的故障報告的異常類型是沒什么道理的,因為故障屏障對所有異常類型一視同仁。應(yīng)變異常就有很大的不同,因為它們的原意是要向方法調(diào)用者傳遞各種情況。你的架構(gòu)可能會指出這些異常應(yīng)該繼承java.lang.Exception或一個指定的基類。

            不要忘記你的異常應(yīng)該是百分百的Java類型,你可以用它來存放為你的特殊目的服務(wù)的特殊字段,方法,甚至是構(gòu)造器。比如,被假想的 processCheck()方法拋出的InsufficientFundsException這個異常類型就應(yīng)該包含著一個 OverdraftProtection的對象,它能夠從另外一個帳戶里把短缺的資金轉(zhuǎn)過來。

          日志還是不要日志

            記錄下故障異常是有用處的,因為日志的目的是在一些需要改正的情況下,日志可以吸引人們的注意力。但對應(yīng)變異常而言卻并非如此。應(yīng)變異常可能代表的只是極少數(shù)情況,但是在你的應(yīng)用里,每一個情況還是會發(fā)生的。它們意味著你的應(yīng)用正在如最初的設(shè)計般正常工作著。經(jīng)常把日志代碼加進應(yīng)變的捕獲塊里會使你的代碼晦澀難懂,而又沒有實際的好處。如果一個應(yīng)變代表了一重要的事件,在拋出一個異常應(yīng)變來警醒調(diào)用者之前,產(chǎn)生一筆日志,記錄下這個事件可能會讓這個方法更好些。

          6 異常的各個方面

            在Aspect Oriented Programming(AOP)的術(shù)語里,故障和應(yīng)變的處理是互相滲透的問題。比如,要實施故障屏障的模式,所有參與的類必須遵循通用規(guī)格:

          • 故障屏障方法必須存活在遍歷參與類的方法調(diào)用圖的最前端
          • 參與類必須使用未檢查的異常來表示故障情況
          • 參與類必須使用故障屏障期望得到的有針對性的未檢查的異常類型
          • 參與類必須捕獲并從低端方法中把在執(zhí)行情境下注定的故障轉(zhuǎn)換成檢查的異常
          • 參與類不能干擾故障異常被傳遞到故障屏障的過程

            這些問題超越了那些本不相干的類的邊界。結(jié)果就是少數(shù)零散的故障處理代碼,以及屏障類和參與類間暗含的耦合(這已經(jīng)比不使用模式進步多了!)。AOP讓故障處理的問題被封裝在通用的可以作用到參與類的層面上。如AspectJ和Spring AOP這樣的Java AOP架構(gòu)認(rèn)為異常的處理是添加故障處理行為的切入點。這樣,把參與者綁定在故障屏障的模式可以放松些。故障的處理可以存活在一個獨立的,不相干的方面里,從而摒棄了屏障方法需要放在方法激活次序的最前頭的要求。

            如果在你的架構(gòu)里利用了AOP,故障和應(yīng)變的處理是理想的在應(yīng)用里用到的在方面上的候選。對故障和應(yīng)變的處理在AOP架構(gòu)下的使用做一個完整的勘探將是將來論文里一個很有意思的題目。

          7 結(jié)論

            雖然Java異常模型自它出現(xiàn)以來就激發(fā)了熱烈的討論,如果使用正確的話,它的價值還是很大的。作為一個設(shè)計師,你的任務(wù)是建立好規(guī)格來最大限度地利用好這個模型。以故障和應(yīng)變的方式來考量異常可以幫助你做出正確的決定。合理使用好Java異常模型可以讓你的應(yīng)用簡單,易維護,和正確。AOP技術(shù)將故障和應(yīng)變定位為相互滲透的問題,這個方法可能會對你的架構(gòu)提供一些幫助。

          8 引用

          • Sun's Exception Tutorial Java異常的基本知識
          • Does Java Need Checked Exception? Bruce Eckel對Java中檢查的異常的異議
          • Exceptional Java  關(guān)于異常的很好的討論,有架構(gòu)式的異常規(guī)則來模仿
          • The Exceptions Debate  來自于developerWorks的關(guān)于異常的來龍去脈
          • The Apache Struts Web Application Framework  Struts的信息源
          • The Spring Framework  Spring框架的信息源
          • Wikipedia: Aspect Oriented Programming  一個很好的對AOP概念的介紹
          • The AspectJ Project  AspectJ的信息源

          posted on 2009-02-12 22:29 suprasoft Inc,. 閱讀(318) 評論(0)  編輯  收藏 所屬分類: J2SE
          ©2005-2008 Suprasoft Inc., All right reserved.
          主站蜘蛛池模板: 彰武县| 巴南区| 六枝特区| 垣曲县| 搜索| 图木舒克市| 交城县| 思南县| 金寨县| 长沙县| 禹城市| 三门县| 乌兰浩特市| 五指山市| 广饶县| 通化县| 临武县| 含山县| 临潭县| 项城市| 丘北县| 枣庄市| 三原县| 呼和浩特市| 同德县| 乌拉特中旗| 光山县| 鄯善县| 克山县| 桓台县| 黄陵县| 延边| 论坛| 白银市| 顺平县| 乌兰察布市| 额济纳旗| 昌平区| 西吉县| 东阿县| 锡林浩特市|