**soluction 1:**return status考慮點如下:**soluction 2:**throw exception
丟擲異常能夠結合事務實現回滾。
兩者的效能,採用拋異常的方式一般而言要損耗更多的效能。
返回狀態的方式,勢必封裝乙個result類,裡面包含status以及需要返回的資料模型,則service所有的介面的返回型別都為result,這是很糟糕的設計。
假設要寫乙個查詢使用者的資訊,方法的定義應該如下:
user getuser
(long id)
;
如果返回型別為result,則定義如下:
result
getuser
(long id)
;
介面的定義受到了實現方案的約束,違背了依賴倒置原則(抽象不應該依賴於細節,細節應當依賴 於抽象。換言之,要針對介面程式設計,而不是針對實現程式設計)。
return status 方式任然需要在上層對status進行判斷,也就是通常情況下controller仍需要關係業務status,並對其做出處理。
丟擲異常可能被日誌採集系統採集到,影響異常治理,這是個小問題,可以不列印業務異常,關鍵在於被採集到後能不能接受。
綜上,在不考慮異常質量的前提下,需要對比兩者的效能開銷,在可接受的範圍內採用拋異常的方式處理業務狀態。
根據經驗而談,異常需要更多的效能開銷,但是多多少,效能開銷在什麼地方,能否優化這些問題需要具體實驗後才能確定。
實驗**如下:
資料型別
/**
* 使用者類
*/class
user
private
final user user =
newuser()
;/**
* 業務異常類
*/class
busines***ception
extends
runtimeexception
}/**
* 通用結果類
* @param */
class
result
public
result
(boolean success, t t)
public
boolean
issuccess()
public t gett()
}
對比方法
/**
* return status方式處理業務狀態
* @param num
* @return
*/private result
getuser1
(int num)
else
}/**
* 拋異常的方式處理業務狀態
* @param num
* @return
*/private user getuser2
(int num)
else
}
ps:為了產生多個狀態,對num的奇偶進行判斷 執行
public
void
start()
}long time2 = system.
currenttimemillis()
;for
(int i =
0; i < max; i++
)catch
(exception e)
}long time3 = system.
currenttimemillis()
; system.out.
println
("getuser1 spend time:"
+(time2 - time1));
system.out.
println
("getuser2 spend time:"
+(time3 - time2));
}
結果:
getuser1 spend time:72究其原因是在預設情況下,建立異常物件時會呼叫父類getuser2 spend time:10044
throwable
的fillinstacktrace()
方法生成棧追蹤資訊,jdk中的原始碼如下:
public
synchronized throwable fillinstacktrace()
return
this
;}
異常的建立:
採用單例模式建立異常,getuser2
方法修改如下
private busines***ception busines***ception =
newbusines***ception()
;/**
* 拋異常的方式處理業務狀態
* @param num
* @return
*/private user getuser2
(int num)
else
}
getuser1 spend time:75可以看到在單例模式下,損耗的效能大幅下降。但是很多情況下我們需要呼叫getuser2 spend time:120
exception(string message)
方法返回異常的原因,此時單例就顯得捉襟見肘了,jdk1.7後threadable
類新增了乙個建構函式:
protected
throwable
(string message, throwable cause,
boolean enablesuppression,
boolean writablestacktrace)
else
detailmessage = message;
this
.cause = cause;if(
!enablesuppression)
suppressedexceptions = null;
}
writablestacktrace
: whether or not the stack trace should be writable
也就是說在業務異常類中,可以通過此建構函式將writablestacktrace
設定為false不去生成異常堆疊資訊,畢竟對於業務異常關心的只是其狀態及原因而已。
修改業務異常類:
/**
* 業務異常類
*/class
busines***ception
extends
runtimeexception
}
result
getuser1 spend time:75可以看出於單例差距甚微,至此對於service層業務狀態的處理應該採用拋異常的方式去處理更合理與優雅。getuser2 spend time:123
業務層錯誤碼處理
最近在做兩件事,一件是整體梳理我這邊業務層的錯誤碼,方便通過錯誤碼立刻確定相應模組。同時以前是直接返回給前台相應的英文提示之類的錯誤,使用者不方便理解,增加使用者體驗 一.錯誤碼優化有關 1 建立乙個錯誤碼的列舉類,方便檢視和統一管理。package exception public enum ex...
dao層 service層 事務的理解
dao層 對應資料最底層操作,一般來說,乙個資料庫table對應乙個dao,單錶操作。service層 把客戶多方面要求進行彙總,對外只有引數即可,至於服務層操作多少個dao與客戶無關。事務四大特性 1.原子性 原子性是指事務是乙個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。2.一致性...
Service層的效能優化
很多學j2ee方向的同學都接觸過s2sh,即傳統的三大框架,學習這三個經典技術的重點就是挖原理和細節,慢慢地我們就能形成一套思想,以幫助理解其他新框架和新技術。學習技術本身並不難,設計技術方案才是難點,為什麼要這麼設計,這樣設計的哲學依據又在哪?不難發現 struts2中控制層的action是多例的...