国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

java - 在MVC開發(fā)模式中,封裝物件應(yīng)該放在Controller還是Service? Controller與Service該如何互動?
伊謝爾倫
伊謝爾倫 2017-05-16 17:05:12
0
8
1593

已經(jīng)學(xué)了兩年的MVC了,但是有些概念還是很模糊,希望能在這裡找到答案。

我曾經(jīng)看到有人說Controller不負責(zé)資料處理,全部交給我們的Service來處理,網(wǎng)頁前端傳回來是什麼資料類型,就直接把資料類型轉(zhuǎn)送到Service,然後由Service來處理;但又有另一個聲音說有時候會同時呼叫多個Service,如果在Controller就將物件封裝好了,就免於在Service的方法中多次封裝。

另外還有一個問題就是關(guān)於Controller與Service互動的問題。
我們?yōu)榱饲岸说目蛻艋恿己?,往往會透過Controller向前端傳回一些錯誤提示,例如使用者名稱已存在,使用者名稱和密碼不符等等??墒翘幚順I(yè)務(wù)邏輯我們是放在Service層,那麼如果把一個login(String username,String password)方法的回傳值設(shè)定為boolean就無法回傳多種錯誤,但是如果回傳String類型,就需要設(shè)定一些基本的字典。
我自己“奇思妙想”,我在Service中通過拋出我自定義的一些RuntimeException,然後在Controller中通過TryCatch來處理不同的錯誤,但是我自己認為這種拋出異常的方式不妥。最近就陷入了迷茫,馬上就要開始做下一個專案了。希望各位能幫我解答一下迷惑。

感謝。

伊謝爾倫
伊謝爾倫

小伙看你根骨奇佳,潛力無限,來學(xué)PHP伐。

全部回覆(8)
phpcn_u1582

我們專案裡分了三層:

  1. 表現(xiàn)層:Spring MVC,負責(zé)接收Http請求、展現(xiàn)(回)結(jié)果、簡單校驗

  2. App層:提供應(yīng)用程式層的功能,例如匯入、匯出、複雜校驗

  3. Domain層:處理業(yè)務(wù)邏輯,例如一些Service

呼叫順序是單項的:Controller->App->Domain

且感知關(guān)係為:Controller->App->Domain,即下層不感知上層

先回答你第一個問題:

你說的第一個問題我是否可以理解為,Http請求過來的參數(shù)不是Object,而是一堆基本型,但你的Service接收的參數(shù)是Object。正確的做法應(yīng)該是,在Controller將「生」參數(shù)轉(zhuǎn)換成Object對象,然後呼叫Service。

為何這樣是正確的?因為Service屬於Domain層,裡面是業(yè)務(wù)邏輯,其接受的參數(shù)應(yīng)該根據(jù)自己的需求而進行設(shè)計,不應(yīng)該考慮Web層過來的參數(shù)是什麼,這樣才可以做到在不同場景下重複使用。

舉個例子,你的Service應(yīng)該可以重複使用不同表現(xiàn)層環(huán)境下:

  1. 在一個Web程式中,使用者傳過來的參數(shù)是POST/GET形式給你的

  2. 在一個Web service程式中,使用者傳過來的參數(shù)是json或SOAP

  3. 在一個Swing程式中,使用者傳過來的參數(shù)就是字串

如果你將Service和具體某個表現(xiàn)層環(huán)境綁定,那麼其方法參數(shù)肯定不穩(wěn)定,結(jié)果就導(dǎo)致無法重複使用。

同理,Service的回傳值也不應(yīng)該和特定場景綁定。

在Spring MVC層面,Controller可以很方便的把參數(shù)轉(zhuǎn)換成Object,相關(guān)文件

第二個問題:

這個問題可以分為三個:

1)簡單的校驗例如參數(shù)長度限制、非空判斷等在哪裡做?

簡單校驗利用Spring MVC的自身提供的機製做,相關(guān)文檔,相關(guān)文檔

2)和Service本身的業(yè)務(wù)邏輯平行的校驗在哪裡做,例如用戶下單時判斷其是否帳號被禁用

我傾向於將這些邏輯校驗放在App層做,Controller調(diào)用App,App調(diào)用兩個不同的Service,將業(yè)務(wù)編織起來

3)和Service本身有關(guān)的業(yè)務(wù)邏輯校驗怎麼做

你舉的是登入的例子,用異常告知呼叫方(Controller)處理結(jié)果沒有任何問題。你也可以豐富Service的回傳值達到這個目的,不過需要注意的是,Service的回傳值的設(shè)計不能和表現(xiàn)層環(huán)境綁定,否則就不能復(fù)用了,這也就是為什麼@YaTou 提到了apache-shiro採用的是異常機制處理認證失敗,因為只有這樣才夠通用。

某草草

我覺得Controller不負責(zé)處理數(shù)據(jù)是正確的, 因為在spring-mvcController是不能復(fù)用的, 但是如果你把業(yè)務(wù)邏輯抽象成Service, 那么這個Service就是可以重複使用的.

至於你說的"在Controller就將物件封裝好了,就免於在Service的方法中多次封裝" , 沒太明白什麼意思, 你每個Service需要什么參數(shù), Controller就給什麼參數(shù), 至於需要的參數(shù)是否需要封裝成對象就可以自己權(quán)衡了.

你所說的login(String username,String password), 你想抽象成Service用異常處理處理多種不同的結(jié)果, 這個我覺得完全沒有問題, 而且我覺得非常好啊, 很多認證框架都用的這種方式, 至少我看的apache-shiro就是用異常處理認證失敗的不同情況的.

曾經(jīng)蠟筆沒有小新

第一個問題感覺沒有標準答案,具體情況具體分析,邏輯分層清晰易於維護就好。

第二個問題的話,你這裡給出的交互是隸屬於權(quán)限控制的,一般用filter、aop、代理、反射等等方式實現(xiàn)代碼收束都可以,異常也在這些集中控制的代碼里扔一次就好,直接在Controller裡硬編碼我反而覺得累贅。 Service這一層更多的是呼叫Dao層的方法來實現(xiàn)一些複雜的涉及多表的業(yè)務(wù)邏輯處理,事務(wù)也放在這一層(當(dāng)然現(xiàn)在框架把這事兒都乾了),所以Service這一層一般不丟異常(參數(shù)驗證在Controller以及之前的層次都做掉了因此不出現(xiàn)業(yè)務(wù)相關(guān)異常,而Dao把資料庫相關(guān)的底層異常屏蔽了)。

當(dāng)然這是個人看法,沒有定式,還是那句話,分層清晰易於維護就好。

滿天的星座

1、Controller預(yù)設(shè)是單例的,但可用@Scope(value = "prototype")替換

2、登入可以回傳int啊,自己加個枚舉

3、規(guī)定是在Service層處理邏輯,要看業(yè)務(wù)的吧,程式碼冗餘度低些好,也好優(yōu)化

大家觀點會不同,做開發(fā)更多的還是優(yōu)化改,降低冗餘度,而不是必須怎麼做。 。 。

伊謝爾倫

1,Controller應(yīng)盡可能的不設(shè)計業(yè)務(wù)邏輯,只涉及交互
2,Service為可復(fù)用的業(yè)務(wù)邏輯
3,Controller為Service的上級調(diào)用方
4,你這個case可以在Service中返回固定的傳回值,在Controller層做判斷,並拋出你想對應(yīng)的例外。

當(dāng)然了這只是我們目前的做法,分享一下。 。 。

迷茫

可以看看我這篇
AOP,MVC——Spring的學(xué)習(xí)以及對CodeIgniter的反思 /a/11...

大家講道理

建議邏輯放在service,我們最近在做分散式微服務(wù)架構(gòu),我們之前是放在controller層的,拆分的時候基本上全部重新,另外有些app需要使用的接口如果放在controller就無法共用,蛋疼吧?

phpcn_u1582

封裝物件到底在Controller還是Service,還是要看具體的情況,個人認為如果是簡單的參數(shù)在Controller中進行封裝時是完全可以的,如果放到Service反而會顯得很冗餘,而且導(dǎo)致Service通用性變差;對於第二個問題,不容同意透過枚舉或不同的狀態(tài)碼來在Controller左做判斷拋出異常,完全可以自己定義一套異常處理機制,直接在Service層拋出,項目有針對此類別業(yè)務(wù)異常的處理機制,直接兩將Service的錯誤訊息和錯誤碼回復(fù)到View層,讓客戶端根據(jù)狀態(tài)碼和錯誤訊息作處理

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板