Web 研發(fā)模式演變

題注:前不久看到「玉伯」一篇很好的文章俭缓,想分享給更多的人看到聋溜,于是就
做了一次搬運(yùn)工。原文在此


前不久徐飛寫了一篇很好的文章:Web 應(yīng)用的組件化開發(fā)。本文嘗試從歷史發(fā)展角度脯倒,說說各種研發(fā)模式的優(yōu)劣实辑。

一、簡單明快的早期時(shí)代

可稱之為 Web 1.0 時(shí)代藻丢,非常適合創(chuàng)業(yè)型小項(xiàng)目剪撬,不分前后端,經(jīng)常 3-5 人搞定所有開發(fā)悠反。頁面由 JSP残黑、PHP 等工程師在服務(wù)端生成,瀏覽器負(fù)責(zé)展現(xiàn)斋否±嫠基本上是服務(wù)端給什么瀏覽器就展現(xiàn)什么,展現(xiàn)的控制在 Web Server 層茵臭。

這種模式的好處是:簡單明快疫诽,本地起一個(gè) Tomcat 或 Apache 就能開發(fā),調(diào)試什么的都還好旦委,只要業(yè)務(wù)不太復(fù)雜奇徒。

然而業(yè)務(wù)總會(huì)變復(fù)雜,這是好事情缨硝,否則很可能就意味著創(chuàng)業(yè)失敗了逼龟。業(yè)務(wù)的復(fù)雜會(huì)讓 Service 越來越多,參與開發(fā)的人員也很可能從幾個(gè)人快速擴(kuò)招到幾十人追葡。在這種情況下,會(huì)遇到一些典型問題:

1奕短、Service 越來越多宜肉,調(diào)用關(guān)系變復(fù)雜敢朱,前端搭建本地環(huán)境不再是一件簡單的事腌且。
考慮團(tuán)隊(duì)協(xié)作,往往會(huì)考慮搭建集中式的開發(fā)服務(wù)器來解決光涂。這種解決方案對(duì)編譯型的后端開發(fā)來說也許還好日杈,但對(duì)前端開發(fā)來說并不友好遣铝。天哪,我只是想調(diào)整下按鈕樣式莉擒,卻要本地開發(fā)酿炸、代碼上傳、驗(yàn)證生效等好幾個(gè)步驟涨冀。也許習(xí)慣了也還好填硕,但開發(fā)服務(wù)器總是不那么穩(wěn)定,出問題時(shí)往往需要依賴后端開發(fā)搞定”饷校看似僅僅是前端開發(fā)難以本地化壮莹,但這對(duì)研發(fā)效率的影響其實(shí)蠻大。

2姻檀、JSP 等代碼的可維護(hù)性越來越差命满。
JSP 非常強(qiáng)大,可以內(nèi)嵌 Java 代碼绣版。這種強(qiáng)大使得前后端的職責(zé)不清晰胶台,JSP 變成了一個(gè)灰色地帶。經(jīng)常為了趕項(xiàng)目僵娃,為了各種緊急需求概作,會(huì)在 JSP 里揉雜大量業(yè)務(wù)代碼。積攢到一定階段時(shí)默怨,往往會(huì)帶來大量維護(hù)成本讯榕。

這個(gè)時(shí)期,為了提高可維護(hù)性匙睹,可以通過下面的方式實(shí)現(xiàn)前端的組件化:

理論上愚屁,如果大家都能按照最佳實(shí)踐去書寫代碼,那么無論是 JSP 還是 PHP痕檬,可維護(hù)性都不會(huì)差霎槐。但可維護(hù)性更多是工程含義,有時(shí)候需要通過限制帶來自由梦谜,需要某種約定丘跌,使得即便是新手也不會(huì)寫出太糟糕的代碼。

如何讓前后端分工更合理高效唁桩,如何提高代碼的可維護(hù)性闭树,在 Web 開發(fā)中很重要。下面我們繼續(xù)來看荒澡,技術(shù)架構(gòu)的演變?nèi)绾谓鉀Q這兩個(gè)問題报辱。

二、后端為主的 MVC 時(shí)代

為了降低復(fù)雜度单山,以后端為出發(fā)點(diǎn)碍现,有了 Web Server 層的架構(gòu)升級(jí),比如 Structs米奸、Spring MVC 等昼接,這是后端的 MVC 時(shí)代。

代碼可維護(hù)性得到明顯好轉(zhuǎn)悴晰,MVC 是個(gè)非常好的協(xié)作模式辩棒,從架構(gòu)層面讓開發(fā)者懂得什么代碼應(yīng)該寫在什么地方。為了讓 View 層更簡單干脆,還可以選擇 Velocity一睁、Freemaker 等模板钻弄,使得模板里寫不了 Java 代碼≌哂酰看起來是功能變?nèi)趿司桨常沁@種限制使得前后端分工更清晰。然而依舊并不是那么清晰复凳,這個(gè)階段的典型問題是:

1瘤泪、前端開發(fā)重度依賴開發(fā)環(huán)境。這種架構(gòu)下育八,前后端協(xié)作有兩種模式:一種是前端寫 demo对途,寫好后,讓后端去套模板髓棋。淘寶早期包括現(xiàn)在依舊有大量業(yè)務(wù)線是這種模式实檀。好處很明顯,demo 可以本地開發(fā)按声,很高效膳犹。不足是還需要后端套模板,有可能套錯(cuò)签则,套完后還需要前端確定须床,來回溝通調(diào)整的成本比較大。另一種協(xié)作模式是前端負(fù)責(zé)瀏覽器端的所有開發(fā)和服務(wù)器端的 View 層模板開發(fā)渐裂,支付寶是這種模式豺旬。好處是 UI 相關(guān)的代碼都是前端去寫就好,后端不用太關(guān)注柒凉,不足就是前端開發(fā)重度綁定后端環(huán)境哈垢,環(huán)境成為影響前端開發(fā)效率的重要因素。

2扛拨、前后端職責(zé)依舊糾纏不清。Velocity 模板還是蠻強(qiáng)大的举塔,變量绑警、邏輯、宏等特性央渣,依舊可以通過拿到的上下文變量來實(shí)現(xiàn)各種業(yè)務(wù)邏輯计盒。這樣,只要前端弱勢(shì)一點(diǎn)芽丹,往往就會(huì)被后端要求在模板層寫出不少業(yè)務(wù)代碼北启。還有一個(gè)很大的灰色地帶是 Controller,頁面路由等功能本應(yīng)該是前端最關(guān)注的,但卻是由后端來實(shí)現(xiàn)咕村。Controller 本身與 Model 往往也會(huì)糾纏不清场钉,看了讓人咬牙的代碼經(jīng)常會(huì)出現(xiàn)在 Controller 層。這些問題不能全歸結(jié)于程序員的素養(yǎng)懈涛,否則 JSP 就夠了逛万。

經(jīng)常會(huì)有人吐槽 Java,但 Java 在工程化開發(fā)方面真的做了大量思考和架構(gòu)嘗試批钠。Java 蠻符合馬云的一句話:讓平凡人做非凡事宇植。

三、Ajax 帶來的 SPA 時(shí)代

歷史滾滾往前埋心,2004 年 Gmail 像風(fēng)一樣的女子來到人間指郁,很快 2005 年 Ajax 正式提出,加上 CDN 開始大量用于靜態(tài)資源存儲(chǔ)拷呆,于是出現(xiàn)了 JavaScript 王者歸來的 SPA (Single Page Application 單頁面應(yīng)用)時(shí)代闲坎。

這種模式下,前后端的分工非常清晰洋腮,前后端的關(guān)鍵協(xié)作點(diǎn)是 Ajax 接口箫柳。看起來是如此美妙啥供,但回過頭來看看的話悯恍,這與 JSP 時(shí)代區(qū)別不大。復(fù)雜度從服務(wù)端的 JSP 里移到了瀏覽器的 JavaScript伙狐,瀏覽器端變得很復(fù)雜涮毫。類似 Spring MVC,這個(gè)時(shí)代開始出現(xiàn)瀏覽器端的分層架構(gòu):

對(duì)于 SPA 應(yīng)用贷屎,有幾個(gè)很重要的挑戰(zhàn):

1罢防、前后端接口的約定。如果后端的接口一塌糊涂唉侄,如果后端的業(yè)務(wù)模型不夠穩(wěn)定咒吐,那么前端開發(fā)會(huì)很痛苦。這一塊在業(yè)界有 API Blueprint 等方案來約定和沉淀接口属划,在阿里恬叹,不少團(tuán)隊(duì)也有類似嘗試,通過接口規(guī)則同眯、接口平臺(tái)等方式來做绽昼。有了和后端一起沉淀的接口規(guī)則,還可以用來模擬數(shù)據(jù)须蜗,使得前后端可以在約定接口后實(shí)現(xiàn)高效并行開發(fā)硅确。相信這一塊會(huì)越做越好目溉。

2、前端開發(fā)的復(fù)雜度控制菱农。SPA 應(yīng)用大多以功能交互型為主缭付,JavaScript 代碼過十萬行很正常。大量 JS 代碼的組織大莫,與 View 層的綁定等蛉腌,都不是容易的事情。典型的解決方案是業(yè)界的 Backbone只厘,但 Backbone 做的事還很有限烙丛,依舊存在大量空白區(qū)域需要挑戰(zhàn)。

SPA 讓前端看到了一絲綠色羔味,但依舊是在荒漠中行走河咽。

四、前端為主的 MV* 時(shí)代

為了降低前端開發(fā)復(fù)雜度赋元,除了 Backbone忘蟹,還有大量框架涌現(xiàn),比如 EmberJS搁凸、KnockoutJS媚值、AngularJS 等等。這些框架總的原則是先按類型分層护糖,比如 Templates褥芒、Controllers、Models嫡良,然后再在層內(nèi)做切分锰扶,如下圖:

好處很明顯:

1、前后端職責(zé)很清晰寝受。前端工作在瀏覽器端坷牛,后端工作在服務(wù)端。清晰的分工很澄,可以讓開發(fā)并行京闰,測(cè)試數(shù)據(jù)的模擬不難,前端可以本地開發(fā)甩苛。后端則可以專注于業(yè)務(wù)邏輯的處理蹂楣,輸出 RESTful 等接口。
2浪藻、前端開發(fā)的復(fù)雜度可控。前端代碼很重乾翔,但合理的分層爱葵,讓前端代碼能各司其職施戴。這一塊蠻有意思的,簡單如模板特性的選擇萌丈,就有很多很多講究赞哗。并非越強(qiáng)大越好,限制什么辆雾,留下哪些自由肪笋,代碼應(yīng)該如何組織,所有這一切設(shè)計(jì)度迂,得花一本的厚度去說明藤乙。
3、部署相對(duì)獨(dú)立惭墓,產(chǎn)品體驗(yàn)可以快速改進(jìn)坛梁。

但依舊有不足之處:
1、代碼不能復(fù)用腊凶。比如后端依舊需要對(duì)數(shù)據(jù)做各種校驗(yàn)划咐,校驗(yàn)邏輯無法復(fù)用瀏覽器端的代碼。如果可以復(fù)用钧萍,那么后端的數(shù)據(jù)校驗(yàn)可以相對(duì)簡單化褐缠。
2、全異步风瘦,對(duì) SEO 不利队魏。往往還需要服務(wù)端做同步渲染的降級(jí)方案。
3弛秋、性能并非最佳器躏,特別是移動(dòng)互聯(lián)網(wǎng)環(huán)境下。
4蟹略、SPA 不能滿足所有需求登失,依舊存在大量多頁面應(yīng)用。URL Design 需要后端配合挖炬,前端無法完全掌控揽浙。

五、Node 帶來的全棧時(shí)代

前端為主的 MV* 模式解決了很多很多問題意敛,但如上所述馅巷,依舊存在不少不足之處。隨著 Node.js 的興起草姻,JavaScript 開始有能力運(yùn)行在服務(wù)端钓猬。這意味著可以有一種新的研發(fā)模式:


在這種研發(fā)模式下,前后端的職責(zé)很清晰撩独。對(duì)前端來說敞曹,兩個(gè) UI 層各司其職:

1账月、Front-end UI layer 處理瀏覽器層的展現(xiàn)邏輯。通過 CSS 渲染樣式澳迫,通過 JavaScript 添加交互功能局齿,HTML 的生成也可以放在這層,具體看應(yīng)用場(chǎng)景橄登。

2抓歼、Back-end UI layer 處理路由、模板拢锹、數(shù)據(jù)獲取谣妻、cookie 等。通過路由面褐,前端終于可以自主把控 URL Design拌禾,這樣無論是單頁面應(yīng)用還是多頁面應(yīng)用,前端都可以自由調(diào)控展哭。后端也終于可以擺脫對(duì)展現(xiàn)的強(qiáng)關(guān)注湃窍,轉(zhuǎn)而可以專心于業(yè)務(wù)邏輯層的開發(fā)。

通過 Node匪傍,Web Server 層也是 JavaScript 代碼您市,這意味著部分代碼可前后復(fù)用,需要 SEO 的場(chǎng)景可以在服務(wù)端同步渲染役衡,由于異步請(qǐng)求太多導(dǎo)致的性能問題也可以通過服務(wù)端來緩解茵休。前一種模式的不足,通過這種模式幾乎都能完美解決掉手蝎。

與 JSP 模式相比榕莺,全棧模式看起來是一種回歸,也的確是一種向原始開發(fā)模式的回歸棵介,不過是一種螺旋上升式的回歸钉鸯。

基于 Node 的全棧模式,依舊面臨很多挑戰(zhàn):

1邮辽、需要前端對(duì)服務(wù)端編程有更進(jìn)一步的認(rèn)識(shí)唠雕。比如 network/tcp、PE 等知識(shí)的掌握吨述。
2岩睁、Node 層與 Java 層的高效通信。Node 模式下揣云,都在服務(wù)器端捕儒,RESTful HTTP 通信未必高效,通過 SOAP 等方式通信更高效邓夕。一切需要在驗(yàn)證中前行刘莹。
3亿笤、對(duì)部署、運(yùn)維層面的熟練了解栋猖,需要更多知識(shí)點(diǎn)和實(shí)操經(jīng)驗(yàn)。
4汪榔、大量歷史遺留問題如何過渡蒲拉。這可能是最大最大的阻力。

六痴腌、小結(jié)

回顧歷史總是讓人感慨雌团,展望未來則讓人興奮。上面講到的研發(fā)模式士聪,除了最后一種還在探索期锦援,其他各種在各大公司都已有大量實(shí)踐。幾點(diǎn)小結(jié):

1剥悟、模式?jīng)]有好壞高下之分灵寺,只有合不合適。
2区岗、Ajax 給前端開發(fā)帶來了一次質(zhì)的飛躍略板,Node 很可能是第二次。
3慈缔、SoC(關(guān)注度分離) 是一條偉大的原則叮称。上面種種模式,都是讓前后端的職責(zé)更清晰藐鹤,分工更合理高效瓤檐。
4、還有個(gè)原則娱节,讓合適的人做合適的事挠蛉。比如 Web Server 層的 UI Layer 開發(fā),前端是更合適的人選括堤。

歷史有時(shí)候會(huì)打轉(zhuǎn)碌秸,咋一看以為是回去了,實(shí)際上是螺旋轉(zhuǎn)了一圈悄窃,站在了一個(gè)新的起點(diǎn)讥电。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市轧抗,隨后出現(xiàn)的幾起案子恩敌,更是在濱河造成了極大的恐慌,老刑警劉巖横媚,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纠炮,死亡現(xiàn)場(chǎng)離奇詭異月趟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)恢口,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門孝宗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人耕肩,你說我怎么就攤上這事因妇。” “怎么了猿诸?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵婚被,是天一觀的道長。 經(jīng)常有香客問我梳虽,道長址芯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任窜觉,我火速辦了婚禮谷炸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘禀挫。我一直安慰自己淑廊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布特咆。 她就那樣靜靜地躺著季惩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腻格。 梳的紋絲不亂的頭發(fā)上画拾,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音菜职,去河邊找鬼青抛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛酬核,可吹牛的內(nèi)容都是我干的蜜另。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼嫡意,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼举瑰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蔬螟,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤此迅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耸序,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忍些,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坎怪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罢坝。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖搅窿,靈堂內(nèi)的尸體忽然破棺而出炸客,到底是詐尸還是另有隱情,我是刑警寧澤戈钢,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站是尔,受9級(jí)特大地震影響殉了,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拟枚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一薪铜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恩溅,春花似錦隔箍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奶稠,卻和暖如春俯艰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锌订。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工竹握, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辆飘。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓啦辐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜈项。 傳聞我的和親對(duì)象是個(gè)殘疾皇子芹关,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 一、簡單明快的早期時(shí)代 1紧卒、Service 越來越多充边,調(diào)用關(guān)系變復(fù)雜,前端搭建本地環(huán)境不再是一件簡單的事〗奖考慮團(tuán)隊(duì)...
    bo_song閱讀 248評(píng)論 0 2
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,777評(píng)論 25 707
  • 3.12植樹節(jié)贬媒,孩子們說想去看看上周植的樹,剛好我也想念山上那青蔥般的綠了肘习。約定的幾個(gè)孩子因?yàn)樘鞖獠缓脹]有來际乘,先到...
    羅俊美閱讀 467評(píng)論 0 0
  • 般若波羅蜜多Imagine/John Lennon 蓍草填詞/江北客@伏羲夢(mèng)蝶@千江尋一客 唱酬黃耀明《拂了一身還...
    江北客閱讀 442評(píng)論 2 3
  • 六六為了表示對(duì)我的歉意,說要請(qǐng)我去王家灣吃燒烤漂佩,吃就吃吧脖含,反正我身上一毛錢也沒有,他掏錢就好投蝉⊙可這身濕漉漉的模樣怎...
    六月孺子牛閱讀 242評(píng)論 0 1