Service層業務狀態的處理

2021-10-20 22:47:29 字數 3819 閱讀 6089

**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

究其原因是在預設情況下,建立異常物件時會呼叫父類throwablefillinstacktrace()方法生成棧追蹤資訊,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

getuser2 spend time:123

可以看出於單例差距甚微,至此對於service層業務狀態的處理應該採用拋異常的方式去處理更合理與優雅。

業務層錯誤碼處理

最近在做兩件事,一件是整體梳理我這邊業務層的錯誤碼,方便通過錯誤碼立刻確定相應模組。同時以前是直接返回給前台相應的英文提示之類的錯誤,使用者不方便理解,增加使用者體驗 一.錯誤碼優化有關 1 建立乙個錯誤碼的列舉類,方便檢視和統一管理。package exception public enum ex...

dao層 service層 事務的理解

dao層 對應資料最底層操作,一般來說,乙個資料庫table對應乙個dao,單錶操作。service層 把客戶多方面要求進行彙總,對外只有引數即可,至於服務層操作多少個dao與客戶無關。事務四大特性 1.原子性 原子性是指事務是乙個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。2.一致性...

Service層的效能優化

很多學j2ee方向的同學都接觸過s2sh,即傳統的三大框架,學習這三個經典技術的重點就是挖原理和細節,慢慢地我們就能形成一套思想,以幫助理解其他新框架和新技術。學習技術本身並不難,設計技術方案才是難點,為什麼要這麼設計,這樣設計的哲學依據又在哪?不難發現 struts2中控制層的action是多例的...