8 回答

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超11個(gè)贊
看上面回答都是一致使用錯(cuò)誤碼來(lái)控制業(yè)務(wù)流程,我來(lái)說(shuō)說(shuō)我自己的想法
什么是異常?
An exception (or exceptional event) is a problem that arises during the execution of a program. When an Exception occurs the normal flow of the program is disrupted and the program/Application terminates abnormally, which is not recommended, therefore these exceptions are to be handled
按照這個(gè)解釋,我們是不是也可以把業(yè)務(wù)上的錯(cuò)誤當(dāng)做一個(gè)異常流程來(lái)處理?
所以當(dāng)業(yè)務(wù)上出現(xiàn)比如題主說(shuō)的「沒(méi)有權(quán)限訪問(wèn)」,可以拋出一個(gè)異常。當(dāng)然也可以通過(guò)接口返回錯(cuò)誤碼的方式完成。
換個(gè)角度來(lái)看這個(gè)問(wèn)題,來(lái)看下Java API
中的一段代碼
public String getCanonicalPath() throws IOException {
if (isInvalid()) {
throw new IOException("Invalid file path");
}
return fs.canonicalize(fs.resolve(this));
}
那我們能不能把這個(gè)接口改成用錯(cuò)誤碼的方式來(lái)傳遞錯(cuò)誤信息呢,當(dāng)然也是可以的。至于Java API
為什么在這里選擇了用異常而不是用錯(cuò)誤碼,我想你也不希望你在你的代碼的中需要對(duì)很多方法進(jìn)行錯(cuò)誤碼判斷吧,而我們的業(yè)務(wù)接口相對(duì)少一點(diǎn),所以如果用錯(cuò)誤碼不會(huì)顯得十分臃腫。
至少到現(xiàn)在為止可以得出一個(gè)結(jié)論結(jié)論:用異常或者用錯(cuò)誤碼來(lái)控制業(yè)務(wù)流程都是可取的,只要整個(gè)團(tuán)隊(duì)統(tǒng)一風(fēng)格就OK了。
回到題主的問(wèn)題上來(lái),用異常來(lái)控制業(yè)務(wù)流程和用錯(cuò)誤碼來(lái)控制到底有什么優(yōu)點(diǎn)和缺點(diǎn)。
用錯(cuò)誤碼控制業(yè)務(wù)流程,需要對(duì)每個(gè)接口的返回都要做一個(gè)錯(cuò)誤碼的校驗(yàn),判斷的代碼會(huì)遍布在你的業(yè)務(wù)代碼里面。優(yōu)點(diǎn)就是對(duì)調(diào)用方,不必對(duì)你的接口進(jìn)行異常校驗(yàn),因?yàn)槟愕慕涌谥豢赡芊祷亍刚_」或者「錯(cuò)誤」,在效率上面也會(huì)更加高一點(diǎn)。對(duì)某些人來(lái)說(shuō),用錯(cuò)誤碼來(lái)控制業(yè)務(wù)流程更能符合「異?!沟恼Z(yǔ)義。
用異常來(lái)控制業(yè)務(wù)流程,可以把錯(cuò)誤處理集中在一處,對(duì)客戶端的代碼編寫更加友好,在業(yè)務(wù)代碼里面不會(huì)有很多錯(cuò)誤碼的判斷。缺點(diǎn)就是創(chuàng)建異常堆棧是需要時(shí)間和空間的,但是可以通過(guò)子類覆蓋父類的fillInStackTrace來(lái)解決。
參考
異常(exception)和執(zhí)行失敗有什么區(qū)別
LongjumpsConsideredInexpensive
Exceptions or error codes

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超4個(gè)贊
我見(jiàn)過(guò)有文章推薦使用try{}catch{}來(lái)進(jìn)行業(yè)務(wù)邏輯處理,理由是Java的異常機(jī)制是由JVM控制的,而且將異常統(tǒng)一拋到最上層由一個(gè)統(tǒng)一的控制器進(jìn)行管理,比如Spring,這樣可以很好的對(duì)異常進(jìn)行管理,等等理由。
個(gè)人覺(jué)得異常就是異常,不可與正常的業(yè)務(wù)邏輯混到一起,異常是錯(cuò)誤的場(chǎng)景,不然也不會(huì)叫做異常,既然是錯(cuò)誤,那么我們要做的應(yīng)該是盡量去避免,但是也不能卡的太死,比如DAO層就不去捕獲異常,而由Service層進(jìn)行捕獲等。

TA貢獻(xiàn)1853條經(jīng)驗(yàn) 獲得超6個(gè)贊
try catch 語(yǔ)句一般都是用于捕獲異常~ 或者runtime人為異常~ 不是那么適合用于業(yè)務(wù)邏輯~
至于判斷是否有權(quán)限看, 那要看你的業(yè)務(wù)需求, 比如一個(gè)業(yè)務(wù)有固定的權(quán)限level, 那么我也可以用switch 去做~ 相對(duì)代碼量會(huì)少很多,

TA貢獻(xiàn)1860條經(jīng)驗(yàn) 獲得超8個(gè)贊
用 if 好。異常應(yīng)該是預(yù)料中可能會(huì)發(fā)生的錯(cuò)誤,而沒(méi)有權(quán)限并非一個(gè)錯(cuò)誤。
catch 可以拋出給核心異常處理器(我比較喜歡的方式,異常統(tǒng)一處理,正常業(yè)務(wù)走正常邏輯,異常走核心異常處理器),也可以由調(diào)用方捕獲(如果需要),具體看業(yè)務(wù)實(shí)現(xiàn)。比如,訪問(wèn)數(shù)據(jù)庫(kù)出錯(cuò)這種,就可以直接拋到核心,生成錯(cuò)誤信息返回即可。如果是訪問(wèn)遠(yuǎn)程服務(wù)器,可能需要有連接出錯(cuò)重試機(jī)制,這個(gè)時(shí)候,就需要把連接異常拋給重連控制器。
這個(gè)不清楚。知道的告訴一下。

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超4個(gè)贊
用戶的權(quán)限寫在數(shù)據(jù)表里面,orm過(guò)來(lái)之后就是用戶類的一個(gè)字段,當(dāng)然用if來(lái)判斷。
如果你不希望代碼塊過(guò)深,可以先寫權(quán)限驗(yàn)證失敗的邏輯,這樣就可以先渲染出失敗的頁(yè)面然后返回:
if(!user.hasAuth())
return render(...);
...
try-catch也有好處,就是統(tǒng)一邏輯,如果if很多,而且失敗時(shí)的邏輯相對(duì)單一(比如就只是顯示個(gè)錯(cuò)誤信息),用異常寫著就比較舒服。但是如果每個(gè)失敗處理不統(tǒng)一,就要定義很多個(gè)不同的異常類,不是特別省事。
凡是能自己定義的東西(不是庫(kù)里面拋出來(lái)的異常),可以用異常的地方也能返回一堆數(shù)據(jù)來(lái)判斷。如果你把業(yè)務(wù)邏輯放進(jìn)DAO,也可以充分利用返回值。所以我寫DAO也好,EJB的SessionBean也好,都是直接返回一個(gè)Result類然后自己判斷。
另外別老想著性能,你用jsp的時(shí)候性能就已經(jīng)被狗吃了。

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超6個(gè)贊
可以用try..catch..
(以下稱為異常),我覺(jué)得此處應(yīng)該用if..
if用于同層中不同部分間的邏輯,如if真/假。異常用于嵌套層次間,如try{..throw..}catch()..
。
區(qū)分描述‘成功’‘失敗’,‘正?!惓!?br/>于是,if
與過(guò)程結(jié)合更緊密——粒度強(qiáng)。而異常
較籠統(tǒng)。
可以先把失敗情況下的信息通過(guò)異常拋出,如果需要,再在異常響應(yīng)過(guò)程(catch)中通過(guò)if細(xì)分判斷;也可在同一個(gè)過(guò)程中通過(guò)if細(xì)分正常情況及異常情況。
兩者響應(yīng)能力亦不同,由于if可能仍在過(guò)程內(nèi),故,能享有過(guò)程中的其他數(shù)據(jù)的訪問(wèn)能力,而異常不可。
看你怎么設(shè)計(jì)/定義兩者的關(guān)系了——偏業(yè)務(wù)角度(if),或在實(shí)現(xiàn)上區(qū)分(異常)。
我覺(jué)得可以問(wèn)自己,兩種情況是否處于同一個(gè)集合(如,真/假),若是,則不應(yīng)使用不同的方式(返回值,或異常)去對(duì)待,若否,則可。
另,我覺(jué)得,通過(guò)異常來(lái)簡(jiǎn)化問(wèn)題處理只是省事,沒(méi)有及時(shí)的(在異常發(fā)生處)進(jìn)行處理,仍是一個(gè)籠統(tǒng)的處理方式
2問(wèn) 不知道。貌似,從調(diào)用棧的頂向底拋,直到被(用戶或系統(tǒng))處理。
3問(wèn) 不知道。(我更關(guān)心業(yè)務(wù)邏輯,如果實(shí)現(xiàn)方式性能差異不夠重要的話)

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超9個(gè)贊
if用于邏輯判斷
try catch是異常處理
完全兩回事吧
你說(shuō)的第一點(diǎn)肯定是用if判斷的
而且JAVA里有一些需要強(qiáng)制異常處理,不然就報(bào)錯(cuò)

TA貢獻(xiàn)1862條經(jīng)驗(yàn) 獲得超6個(gè)贊
if(有權(quán)限)
能用的前提是假定別人也遵守. "遵守"在語(yǔ)法上是個(gè)可選的行為, 但是權(quán)限檢查絕對(duì)不能是可選的. 所以總歸要有異常, 那又何必多此一舉提供另一種if的版本.
異常的另一個(gè)好處是連可能的錯(cuò)誤都沒(méi)法無(wú)視, 不catch連編譯都不行
添加回答
舉報(bào)