實現真正意義上的前后端分離------由淘寶引入nodejs引發的思考


說起前后端分離,大家包括我自己都會想到:

當今流行的MVC不就是最標准的前后端分離嗎?

說到這里,我不禁要反問,MVC真正的實現了前后端分離了嗎?

無論是PHP的MVC框架TP還是JAVA的MVC框架SpringMVC,他們實現的前后端分離或許應該被叫做:一定程度上的邏輯和展示的分離

當然我們不能泯滅MVC帶來的貢獻,MVC的出現讓寫代碼不再是一行寫到底,他給我們帶來了分層的概念,並在一定的程度上減少了三層間的糾纏。

但是,我們回憶一下當我們基於MVC寫代碼的時候,是不是有這樣的情況:

這樣的一個新聞列表(html+php)

<div class="news">

<?php

foreach($results as $item){

?>

<li class='news_item'><a href="<?php echo $item['url'];?>"><?php echo $item['title'];?></a></li>

<?php

}

?>

</div>

或則是:這樣的一個分頁(jsp)

<table>

<tr><th>名字</th><th>說明</th><th>圖片預覽</th></tr>

<c:forEach items="${data}" var="item">

<tr><td>${item.advertName}</td><td>${item.notes}</td><td><img src="${item.defPath}"/></td></tr>

</c:forEach>

</table>

<ul>

<li><a href='?nowPage=${nowPage-1}'>上一頁</a></li>

<c:forEach varStatus="i" begin="1" end="${sumPage}"> <c:choose> <c:when test="${nowPage==i.count}">

<li class='disabled'>${i.count}</li>

</c:when>

<c:otherwise>

<li class='active'><a href='?nowPage=${i.count}'>${i.count}</a></li>

</c:otherwise>

</c:choose>

</c:forEach>

<li><a href='?nowPage=${nowPage+1}'>下一頁</a></li>

</ul>

在這些個項目中我們的開發人員就是在view層不斷的“挖坑”和不斷的“填坑”,而且雖然我們用到MVC框架,但是我們並沒有真正的實現前后端分離。

如何實現前台人員就寫前台,后台人員只管后台,這是我一直在思考的問題。

無論是為了滿足業務上的需求:比如,前端變化頻繁,或者前端效果要求非常高/跨設備的兼容性要求很高的情況下

還是為了使技術團隊更加精進所在領域,團隊分工更加明確,能和需求更好對接(界面問題歸前台,業務功能開發歸后台)的角度來看,我覺得做好前后端分離,是團隊建設的很重要的一部。

當然這也是在公司有一定經濟基礎的條件下,我也是一個實用主義者,提倡為了業務而技術,而不是為了技術而技術。

 

------------------------說了這么多,大多都是我個人開發中遇到的一些情況和問題,下面開始正題了----------------------

 

聽聞淘寶引入Nodejs來實現了淘寶團隊的前后端分離,下面就看看常見的做法和淘寶的做法,供大家思考

web架構的發展經歷了(也可以說正在經歷)從后端為主MVC應用時代---->基於Ajax的SAP應用時代---->以前端為主的MV*時代---->基於Nodejs的全棧時代

這個過程也是隨着經濟發展,人們對審美,性能要求不斷提升而發展來的。

在各個時代前后端配合的方式也不一樣,分別看一下:

后端為主MVC應用時代

  在MVC架構中一般是前端人員寫模板,給后台人員套用,這就是上面說的那種情況,前后台糾纏不清,到最后就是大家一起寫了,前台后台一起大包干,根本沒有分工了。

 

基於Ajax的SAP應用時代

  隨着2004年gmail的誕生,隨后也誕生了Ajax,它的到來讓SPA瘋狂了一把,這個時代前后台分工還算是很明晰的,后台提供接口,前台來調用。  

  同時也帶來了一大堆的問題,前端代碼過於復雜,而且前台嚴重依賴后端接口,如果后端數據模型不穩定經常變化,那么前台開發人員就會很痛苦,所謂牽一發動全身。可維護性很差,而且代碼難修改。

 

以前端為主的MV*時代

  前幾年出現了各種前端框架,有mvc的Backone,有MVVM的angularjs等。。。

  這些框架總的原則是先按類型分層,比如 Templates、Controllers、Models,然后再在層內做切分,

  這個時代的應用實現了前后端分離,前端工作在瀏覽器端,后端工作在服務端。清晰的分工,可以讓開發並行,測試數據的模擬不難,前端可以本地開發。后端則可以專注於業務邏輯的處理,輸出 RESTful 等接口。

  但是,這種應用全是異步請求,對SEO不利,前后台都要寫邏輯控制,而且無法復用前后台的代碼,存在一定程度上的重復開發。URL的設計要嚴重依賴配合后端,無法自主決定。

 

基於Nodejs的全棧時代

  隨着 Node.js 的興起,JavaScript 開始有能力運行在服務端。這也帶來了全新的架構:

 

  這種架構下,存在兩個UI Layer層,即他們都負責前台的工作:

    基於瀏覽器的UI layer處理瀏覽器層面的展示邏輯,通過CSS控制樣式,js添加交互功能,HTML 的生成也可以放在這層。

    基於Nodejs的UI layer處理路由,模板,獲取數據,cookie等。通過路由,前端終於可以自主把控 URL Design,這樣無論是單頁面應用還是多頁面應用,前端都可以自由調控。

    這樣一來,后端終於可以擺脫對展現的強關注,轉而可以專心於業務邏輯層的開發。此時,web server上也是javascript代碼,所以一定程度上“前后台”可以復用了,對於需要SEO的場景我們可以在服務端上進行渲染。

    這樣基本解決了MV*時代的一些弊病。

 

-------------------------------講了這么多,我們看看淘寶到底是怎么利用Nodejs實現前后端分離的----------------------------

 

借一張網友的圖:

 

看看網友的分析:

  1. 最上端是服務端,就是我們常說的后端。后端對於我們來說,就是一個接口的集合,服務端提供各種各樣的接口供我們使用。因為有Node層,也不用局限是什么形式的服務。對於后端開發來說,他們只用關心業務代碼的接口實現。
  2. 服務端下面是Node應用。
  3. Node應用中有一層Model Proxy與服務端進行通訊。這一層主要目前是抹平我們對不同接口的調用方式,封裝一些view層需要的Model。
  4. Node層還能輕松實現原來vmcommon,tms(引用淘寶內容管理系統)等需求。
  5. Node層要使用什么框架由開發者自己決定。不過推薦使用express+xTemplate的組合,xTemplate能做到前后端公用。
  6. 怎么用Node大家自己決定,但是令人興奮的是,我們終於可以使用Node輕松實現我們想要的輸出方式:JSON/JSONP/RESTful/HTML/BigPipe/Comet/Socket/同步、異步,想怎么整就怎么整,完全根據你的場景決定。
  7. 瀏覽器層在我們這個架構中沒有變化,也不希望因為引入Node改變你以前在瀏覽器中開發的認知。
  8. 引入Node,只是把本該就前端控制的部分交由前端掌控。

 

  

  然后給了一個淘寶應用的例子:

  淘寶寶貝詳情頁靜態化之后,還是有不少需要實時獲取的信息,比如物流、促銷等等,因為這些信息在不同業務系統中,所以需要前端發送5,6個異步請求來回填這些內容。
  有了NodeJS之后,前端可以在NodeJS中去代理這5個異步請求,還能很容易的做Bigpipe,這塊的優化能讓整個渲染效率提升很多。
  可能在PC上你覺得發5,6個異步請求也沒什么,但是在無線端,在客戶手機上建立一個HTTP請求開銷很大,有了這個優化,性能一下提升好幾倍。

  

----------最后我們總結一下-------------------

前后端分離的目的:

 

  前端:負責View和Controller層。更有甚者,引入Nodejs直接請求服務端,繞過后端數據處理。

  后端:負責Model層,業務處理/數據等。

前后端分離的意義:

  技術上,分工更專業

  業務上,溝通更便利

 

 

參考文獻:

http://blog.sina.com.cn/s/blog_15ac991410102wtz7.html  設計和編程並走

http://blog.jobbole.com/65509/  lifesinger (@玉伯也叫射雕) 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM