重審業務邏輯
用過MVC的童鞋都知道業務邏輯(Bussiness Logic),但是大多對這概念又是模稜兩可,業務邏輯從來都是這樣難以理解,談論前後端分離之前這個概念非常有必要探討一下!
在簡單的CRUD的系統中,基本上都是對資料進行增刪改查操作,並沒有多少業務邏輯可言;但像銀行系統對金融資料的操作就顯得不那麼簡單了,以轉賬為例:A給B轉帳轉100元,簡易程式碼如下:
if(A.balance - 100 >= 0){
A.balance -100;
B.balance +100;
}else{
//返回異常資訊
}
這串程式碼已經不僅僅是對資料的增刪改查了,它包含了一些業務規則,比如A的餘額如果少於100,這個程式碼會返回異常資訊提示"餘額不足",類似於這種,一組和特定領域業務相關而又不可拆分的程式碼,可以看作業務邏輯的實現。所以轉賬是作為一部個不可拆分的整體提供給使用者的,也就是說Business層是不可能給你提供一個"A.餘額+x"這種介面的,如果你想轉賬,請用轉賬方法,方法裡面怎麼對資料操作,你無需關心,你也沒法關心。
=====
這裡注意強調一下:頁面/渲染邏輯和業務邏輯的區別,頁面通常需要多個資料用來展示,比如網上銀行介面即顯示使用者名稱、餘額和轉賬記錄等,這些資訊的組合稱作頁面/渲染/展示邏輯,並不等於業務邏輯,業務邏輯只應提供基本的業務資料而不應該和頁面邏輯摻和起來,就拿這個例子來講,頁面的這些資料,service層會提供三個介面來支援頁面資料的產出,但並不會給你拼到一塊給你,拼接不同的業務資訊組合成一個View Object只能是脫離於service之外的層處理,在此特地分清頁面邏輯和業務邏輯的關係
前後端定義
既然是談前後端分離,就必須,必須,必須先劃出前後端的定義,要不然談來談去,最後大家敢情不是說的一塊事。其實前後端的概念真是一人一個看法,有人覺得和瀏覽器相關的技術這幫就屬於前端,牽扯到了java程式碼的就屬於後端;也有人覺得前段不僅包括瀏覽器技術棧線,還包括後臺像jsp等模板技術相關技術也屬於前端,後端純粹是service那塊的技術。在這裡我說下我的看法。
不同人對前後端的定義的不同是因為看待角度的不同,有人以工作職責分,有人以技術棧分;這裡我覺得應該以業務邏輯為分割線去分!(明白為啥我一上來先說業務邏輯了吧·—·)
為什麼我會以業務邏輯去分割前後端的定義,這麼說吧,一個系統的展現形式可能會有很多種:Web、Web Service、桌面客戶端等,他們無一例外都是和使用者直接打交道的,像網上銀行的Web網頁、手機APP,他們採用不同的技術和互動實現了與系統的互動,而整個系統有一部分是不隨展現形式而變的——業務邏輯程式碼,也就說轉賬這個業務無論是在Web還是App中,對資料的操作邏輯是不變的,所以我們很自然的就會形成一個分隔:
最基本的一部分是專注與實現業務邏輯程式碼的實現,是不隨展現形式而改變的;另一部分是用來給使用者展現的,可能隨著技術潮流改變而改變(說不定過一段時間就出VR版的網銀了,哈哈);我稱前者為後端,後者為前端。也就是說所有針對業務邏輯去實現的部分是後端,用來展現資料和使用者互動的部分屬於前端。
=====
對應到傳統的MVC上來,service層就是後端,而service依賴dao層,dao層也屬於後端,而Controller既不屬於前端也不屬於後端,他只是作為Server對外提供的一層HTTP訪問方式的介面,是後端的門口;而Browser的技術棧線全都屬於前端,這裡前端並僅不限於browser,任何用於實現特定顯示方式的部分都屬於前端:比如我為了更好的將資料拼接成組合渲染邏輯物件,可以再加一層nodejs作為中間層,當然這也是劃為前端。如下圖:
圖1
前後端分離
何為前後端分離?前後端本來不就分離麼?這要從尷尬的jsp講起。分工精細化從來都是蛋糕做大的原則,多個領域工程師最好在不需要接觸其他領域知識的情況下合作,才可能使效率越來越高,維護也會變得簡單。jsp的模板技術融合了html和java程式碼,使得傳統MVC開發中的前後端在這裡如膠似漆,前端做好頁面,後端轉成模板,發現問題再找前端,前端又看不懂java程式碼...前後端分離的目的就是將這尷尬局面打破。
什麼是前後端分離?前後端分離說白了就是把前端和後端分成兩個工程,由不同的團隊負責開發,這樣從工程和職責的角度上都有分開,這樣,後端偏向於提供單純的API介面,前端就是呼叫API介面進行展示和業務呼叫。
這樣不僅將頁面渲染和業務邏輯從server剝離開來,將頁面渲染放給前端,甚至放給瀏覽器;將業務邏輯放給後臺專心搞業務,降低了他們之間的耦合性,而且從職責上進行了分明,更適合大專案和大團隊管理和開發。
解決方案
我也提不出什麼解決方案,比較有名的屬淘寶UED的中途島專案,我談談我大概的實現方案。
首先Server端是RESTful風格的,簡單的只提供API的訪問介面;Browser端進行對HTML的展示,配合ajax非同步請求和Angular、React等前端成熟框架進行頁面渲染;但browser自己勢單力薄,所以要多出一層處理資料的nodejs(不限死nodejs),用來處理頁面邏輯資料、session、渲染初始頁面等工作,所以大致的原理圖如圖1所示。
總結
前後端分離可能並不適用於所有情況。軟體開發嘛,都知道沒有最好,只有最合適,能用比較合適的手段去實現軟體的目標,也算功德圓滿了。
我記得我們班裡有次活動,有兩個小夥子被挑出來做遊戲,每個人原地轉10圈,再轉暈之後,面前有兩臺電腦,導師開口出題,要求一分鐘用java敲出一個菱形圖案,其中一個馬上大腦急速轉動,分析規律,螢幕上只見他熟練的for迴圈語句敲的飛快,雖然有些許卡住,但是就在他敲得起興的同時,另一位採用system.out.print()的方式,快速的敲了個菱形圖案出來,不過被老師制止:"必須用for迴圈!",這句話對我就觸動挺深,做軟體究竟是為了水平的提高,還是真正的實現需求?
以上也只是個人的一些心得和看法,有任何不妥和錯誤的地方歡迎指出。