日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
我們什么時(shí)候應(yīng)該使用異常?

先說個(gè)題外話: 在公司做了倆件事, 是我覺得很有意義的, 第一就是成立了一個(gè)PHP郵件組, 第二就是成立了一個(gè)Hi群. 目前倆者都有超過500 phpers在里面. 我一直認(rèn)為, 構(gòu)建一個(gè)交流平臺(tái), 讓同學(xué)們能順暢, 簡單的溝通, 是營造積極的技術(shù)學(xué)習(xí)氛圍的基礎(chǔ)和前提. 讓每個(gè)人的問題不會(huì)成為別人的問題, 則是最直接的利益. (后記: 不少人都問郵件組地址, 實(shí)在不好意思, 這個(gè)郵件組是公司內(nèi)部的郵件組, Hi也是公司內(nèi)部的. 謝謝)

昨天, 有同事在郵件組提了個(gè)問題:

PHP應(yīng)該什么時(shí)候使用 Exception ? 它的性能如何?

這個(gè)問題也算是一個(gè)久經(jīng)爭論的經(jīng)典問題了. 我談?wù)勎业膫€(gè)人看法.

異常與之對(duì)應(yīng)的錯(cuò)誤碼(或者狀態(tài)碼), 到底各自有什么優(yōu)點(diǎn), 缺點(diǎn), 我們應(yīng)該怎么使用呢?

錯(cuò)誤碼

首先來說, 異常機(jī)制是在錯(cuò)誤碼機(jī)制之后才出現(xiàn)的, 那么根據(jù)進(jìn)化論, 異常自然是避免了錯(cuò)誤碼機(jī)制的一些不足. 這些不足包括.

1. 錯(cuò)誤信息不豐富

函數(shù), 只能有一個(gè)返回值(當(dāng)然, Lua可以返回多個(gè), 但其實(shí)也相當(dāng)于在PHP中返回一個(gè)數(shù)組), 我們見過最多的函數(shù)說明就是: 成功時(shí)候返回***, 錯(cuò)誤的時(shí)候返回FALSE, 然而一個(gè)函數(shù)出錯(cuò)我原因可能有多種, 出錯(cuò)的種類更有多種. 一個(gè)簡單的FALSE, 并不能把具體的錯(cuò)誤信息告訴調(diào)用者.

于是, 我們也就見過一些, 這樣的函數(shù)說明: 如果返回值大于0, 則表示成功的狀態(tài)碼, 如果返回值小于0, 則表示出錯(cuò)的狀態(tài)碼.

然而, 這個(gè)要求函數(shù)是返回整形(或者數(shù)字), 對(duì)于一些其他函數(shù), 我們并不能通過0, >0, <0來判別, 并且, 即使通過這樣的方式, 我們還需要用返回的錯(cuò)誤碼和一些預(yù)定義宏(或者調(diào)用類似strerror())來獲取具體的, 可讀的錯(cuò)誤信息.

于是, 就有一些函數(shù)使用全局的錯(cuò)誤碼, 和錯(cuò)誤信息, 來保存具體的錯(cuò)誤信息, 這個(gè)時(shí)候我們就看到這樣的函數(shù)描述: 成功返回***, 出錯(cuò)的時(shí)候返回FALSE, 錯(cuò)誤代碼保存在全局變量$errno中(至少大多數(shù)Linux庫函數(shù)是這樣描述的, 呵呵).

Okey, 這樣的方式確實(shí)可以工作, 但是, 是不是覺得, 很丑陋呢?

2. 加入錯(cuò)誤狀態(tài)碼可能需要改變函數(shù)簽名

假設(shè), 你編寫了一個(gè)函數(shù), 這個(gè)函數(shù)很簡單, 很簡單, 你認(rèn)為他絕對(duì)不會(huì)出錯(cuò), 于是你申明為(用C語言為例, PHP沒有返回類型提示):

 
 
 
  1. void dummy() {  

但是后來你慢慢修改了這個(gè)函數(shù), 給了它更多的功能, 此時(shí)這個(gè)函數(shù)可能會(huì)失敗了. 而你現(xiàn)在根本無法為這個(gè)函數(shù), 加入錯(cuò)誤返回碼了.

也許有人說PHP沒有返回值類型限制一說, 但是想想PHP的構(gòu)造函數(shù), 構(gòu)造函數(shù)是沒有返回值的, 當(dāng)發(fā)生錯(cuò)誤的時(shí)候, 如果你不使用異常, 我想你只能選擇die, 或者使用2中的方法來錯(cuò)誤繼續(xù)執(zhí)行了.

另外, 在一個(gè)良好的軟件系統(tǒng)中, 返回類型其實(shí)也是約定俗成的, 當(dāng)所有的使用的函數(shù)的地方, 都沒有檢查返回值的時(shí)候, 你還是無法為這個(gè)函數(shù)加入錯(cuò)誤返回碼.

3. 錯(cuò)誤狀態(tài)碼可能會(huì)被忽略

當(dāng)你的一個(gè)函數(shù), 出錯(cuò)了, 返回了錯(cuò)誤狀態(tài)碼, 而調(diào)用方并沒有檢測這個(gè)返回值, 會(huì)發(fā)生什么情況呢? -_#. 令一方面, 處處檢測返回狀態(tài)碼, 會(huì)造成代碼非常的,,ugly:

 
 
 
  1.   if (!call1()) {  
  2.       die();  
  3.   }  
  4.    if (call2() != SUCCESS) {  
  5.      die();  
  6.   }  
  7.    if (call3() < 0) {  
  8.       $msg = error_get_last();  
  9.       die($msg["message"]);  
  10.   } 

異常機(jī)制

那么現(xiàn)在我們來看看異常機(jī)制, 如果我們采用異常機(jī)制, 上面的代碼可以寫作:

 
 
 
  1. try {  
  2.    call1();  
  3.    call2();  
  4.    call3();  
  5. } catch (Exception $e) {  
  6.    die($e->getMessage());  

更方便的, 如果你的代碼只是中間層, 你的調(diào)用方會(huì)負(fù)責(zé)處理錯(cuò)誤的話, 你甚至可以簡單的寫作:

 
 
 
  1. function myFunc() {  
  2.    call1();  
  3.    call2();  
  4.    call3();  

而一個(gè)異常對(duì)象, 可以包含更豐富的錯(cuò)誤信息, 比如錯(cuò)誤信息, 錯(cuò)誤碼, 錯(cuò)誤的行數(shù), 文件, 甚至出錯(cuò)上下文, 等等, 避免的”1.錯(cuò)誤信息不豐富”的不足.

我們也可以為一個(gè)返回void類型的函數(shù)增加異常, 而不改變他的函數(shù)簽名, 也就不會(huì)有上面說的”2.加入錯(cuò)誤狀態(tài)碼可能需要改變函數(shù)簽名”. 對(duì)于PHP來說, 如果我們新加入的錯(cuò)誤沒有被捕捉, 也不用擔(dān)心, 會(huì)明顯的出錯(cuò)的. 也就不會(huì)發(fā)生上面所說的”3. 錯(cuò)誤狀態(tài)碼可能會(huì)被忽略”的情況.

然而, 也有一些反對(duì)使用異常的聲音:

1. 性能

正如文章開頭提問中的: “它的性能如何?”, 異常機(jī)制確實(shí)要比返回狀態(tài)碼的方式昂貴一些, 對(duì)于C++來說, 在異常發(fā)生的時(shí)候, 還要發(fā)生堆棧解退。

性能和方便, 往往是一個(gè)矛盾體, 我只能說, 你需要權(quán)衡, 如果你寫的是一個(gè)小的模塊, 并且它的生命期可能很短, 也不需要什么特殊的設(shè)計(jì)模式, 那我覺得你可以不用異常.

而如果你在為一個(gè)龐大的軟件做開發(fā), 我想你更應(yīng)該看重的, 應(yīng)該是, 它的可擴(kuò)展性, 可維護(hù)性.

2. 太多可能的Uncaught Exception

如果, 你調(diào)用了一個(gè)可能發(fā)生異常的函數(shù), 但是卻沒有捕獲這個(gè)異常, okey, Fatal Error了, 所以讓我們的代碼看起來:

 
 
 
  1. try {  
  2. } catch () {  
  3. }....  
  4.  try {  
  5. } catch () {  
  6. }....  
  7. try {  
  8. } catch () {  

然而, 這個(gè)是可以經(jīng)過良好設(shè)計(jì)避免的, 比如我在設(shè)計(jì)Yaf的時(shí)候, 就提供了全局異常處理, 也就是類似于, 你在最最頂層, 加上了一個(gè)try catch, 所有的異常錯(cuò)誤邏輯都加到這個(gè)里面, 你也可以很方面的把你自己的異常加進(jìn)去.

結(jié)論

經(jīng)常有人批評(píng)我是倆面派, 呵呵, 但是在大家了解了上面的利弊以后, 是否也會(huì)和我一樣認(rèn)為: 這個(gè)事情沒有定論呢? 一切從實(shí)際出發(fā).

原文鏈接:http://www.laruence.com/2012/02/02/2515.html


文章名稱:我們什么時(shí)候應(yīng)該使用異常?
文章位置:http://www.dlmjj.cn/article/cdsisgi.html