五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > Web前端的弱架構(gòu)導(dǎo)致的代碼污染

Web前端的弱架構(gòu)導(dǎo)致的代碼污染

文章來源:365jz.com     點擊數(shù):236    更新時間:2009-09-30 11:59   參與評論
主機網(wǎng)全新上線,買空間、服務(wù)器就上主機網(wǎng),安全有保障!CNIDC.COM

就要開始新的項目了,全站的前端架構(gòu)也要開始構(gòu)思,得益于之前做雅虎關(guān)系時的一些或成功或失敗的實踐總結(jié),還是應(yīng)當(dāng)從架構(gòu)的層面著手,去解決一些前端團隊開發(fā)的問題。如今市面上有著各種各樣的js庫和框架,但庫和框架還是有很大區(qū)別的,首先,“庫”是widget的一個集合,特點是上手容易使用簡便,參照例子只大概只需要引用一個script標(biāo)簽到頁面中,再加上一些簡單的類似a.start(config)的啟動代碼就可以了,而框架則是網(wǎng)站的樹狀結(jié)構(gòu)的抽象,包括模塊關(guān)系,功能之間的依賴,入口的先后順序,以及性能的hack等等,幸運的是阿里還是很明智的選擇了yui作為其前端架構(gòu)的底層,只是由于yui2強大豐富的widget庫,使得多數(shù)人認(rèn)為yui2更是一個庫而非框架,而yui2的yuiloader也僅僅是一個可選的模塊,這樣就更加淡化了yui2在框架層面靈活強大的表現(xiàn)力,個人認(rèn)為如果網(wǎng)站沒有以yuiloader搭建起來的模塊樹做支撐,yui2的作用無疑是一把牛刀只用作殺雞而已。在yui3中,這種情況有了根本改變,框架層面的模塊化代替了簡單的庫,這對于團隊開發(fā)的大型網(wǎng)站是很有啟發(fā)的。

當(dāng)然,在做前端開發(fā)的時候,使用loader必然要多寫幾行代碼,多幾次封裝,又麻煩又不方便,這樣做到底好在什么地方呢。這個話題大概說來話長,這里只從網(wǎng)站規(guī)模和項目特點的方面來作簡單說明:

像taobao這種大型的網(wǎng)站,前端開發(fā)占有不小的比重,這類網(wǎng)站一般會按照大類劃分成不同的產(chǎn)品,每個產(chǎn)品相當(dāng)于一個獨立完整的網(wǎng)站,只有整體樣式風(fēng)格和組件會和主戰(zhàn)保持一致。

那么從web前端角度講,這類網(wǎng)站大致包含四部分內(nèi)容:

1),網(wǎng)站下轄站點所需的全局變量和函數(shù),包括所有子站共通的部分

2),子站外框(公共頭尾)

3),網(wǎng)頁主體內(nèi)容

4),組件

根據(jù)三者的特點,各自的重用情況為:

1),全站的全局變量和函數(shù):幾乎每個頁面都要用到

2),子站外框:幾乎每個子站的網(wǎng)頁都保持一致

3),網(wǎng)頁的主體內(nèi)容,不可重用

4),組件:重用率高,但是被有選擇的調(diào)用,只在必要的時候才會引用組件

從需求的角度上講,這類網(wǎng)站的特點是更新頻繁,從工程的角度講,代碼的維護成本大于甚至遠(yuǎn)遠(yuǎn)大于代碼開發(fā)成本。也就是說項目隨著時間的推移,修改功能的項目數(shù)量要遠(yuǎn)遠(yuǎn)大于新功能的開發(fā),到項目的中后期,工程師的大部分時間不是寫新代碼,而是花大量的經(jīng)歷去讀舊代碼,或者進(jìn)行性能優(yōu)化,或者針對新需求進(jìn)行改進(jìn)。不管是性能改進(jìn)還是需求改進(jìn),都將增加代碼的熵,代碼污染也會越來越嚴(yán)重,維護成本也會急劇變大,這讓項目后期開發(fā)工程師苦不堪言,有一部分原因是項目前期文檔不全,缺少寫代碼的必要的約束和約定,再者是注釋不夠及時和規(guī)范,導(dǎo)致代碼可讀性差,三是工程師水平參差不齊,有些人在修改代碼過程中會無意識的破壞原有代碼的結(jié)構(gòu),四是時間壓力導(dǎo)致代碼質(zhì)量下降,五是框架結(jié)構(gòu)的不合理。

完善文檔和規(guī)范、增加新人培訓(xùn)力度可以以解決一部分問題,但這往往和制度和執(zhí)行力度有關(guān)。從項目生命周期來看,項目分為疊代和快速開發(fā),快速開發(fā)是開發(fā)時間短,不需要和其他項目并行,及時開發(fā)及時測試及時打包上線,和其他項目發(fā)生沖突的可能性很小,簡單迭代的開發(fā)模式是基于分支和主干的多線程的并行開發(fā)。在此基礎(chǔ)上的前端開發(fā)也是保持和后段開發(fā)同步的迭代。迭代的優(yōu)點是項目并行和減少沖突的發(fā)生。從后端開發(fā)的角度看,經(jīng)常多人開發(fā)同一個頁面,只是每個工程師負(fù)責(zé)的模塊不同而已,一般情況下頁面中只有include的入口,然后調(diào)用各自工程師的代碼,這樣在頁面中的代碼污染就比較低,但是隨著頁面復(fù)雜度的增加,后段代碼會越來越多的直接出現(xiàn)在頁面當(dāng)中,比如使用更多的echo代替模版,html代碼中嵌套更多的if判斷和for循環(huán)。這樣會增加代碼污染的程度。從前端開發(fā)來看,也會經(jīng)常出現(xiàn)多人合作開發(fā)同一個頁面,也是每人負(fù)責(zé)不同的功能模塊,這里有兩種情況,1是多人同時開發(fā)不同的應(yīng)用模塊,兩者沒有依賴關(guān)系,2是多人分別開發(fā)框架和應(yīng)用,兩者之間有依賴關(guān)系,應(yīng)用依賴框架。而兩者之間的耦合應(yīng)當(dāng)僅僅以入口調(diào)用作為接口,因此前端框架應(yīng)當(dāng)考慮到這種情況,即多人開發(fā)的前端功能代碼應(yīng)當(dāng)盡可能地分離。

在js代碼的寫法上,自然推薦將代碼都封裝到頁面的js文件中,在page中只留出入口。然而實際情況并非如此,在缺少框架約束的情況下,多數(shù)人不會選擇去在讀懂之前的爛代碼的基礎(chǔ)上再添加自己的代碼,通常會直接用最簡單粗暴的用script標(biāo)簽引一個js,緊跟著開一段script代碼塊寫啟動入口,甚至于連script標(biāo)簽都爛的寫,直接在原先代碼塊中直接開辟一段區(qū)域自己加代碼。這種做法應(yīng)當(dāng)如何看待呢?從庫的角度講,庫中給了很多模塊的實例,使用模塊的方式大都也是手寫一個script標(biāo)簽引一個js文件,然后再頁面中添加啟動入口。那么當(dāng)多人開發(fā)同一個頁面中的不同功能的時候就會這樣做:

主機網(wǎng)全新上線,買空間、服務(wù)器就上主機網(wǎng),安全有保障!CNIDC.COM

首先,a在頁面中實現(xiàn)了一個功能,大致是這個樣子:

《script src=“base.js” /》《!--庫的種子--》《script src=“a.js” /》《script》a.start();《/script》

b也實現(xiàn)了另外一個功能,大致是這個樣子:

《script src=“base.js” /》《!--庫的種子--》《script src=“b.js” /》《script》b.start();《/script》

b在coding的時候多數(shù)情況不會去review頁面代碼,或者說review了頁面的爛代碼也看不懂,再或者說兩個人并行開發(fā),并不知曉對方的實現(xiàn)。這樣就會導(dǎo)致base.js的引用重復(fù)。

另外一種情況是,如果一個例子比較復(fù)雜,需要引用多個js文件,比如:

《script src=“base.js” /》《!--庫的種子--》《script src=“a.js” /》《script src=“b.js” /》《script》m.start();《/script》

那么a.js和b.js的引用順序則需要特別注意,但在實際開發(fā)中,并不能保證每個人都能細(xì)心的將js文件的順序排好,如果排亂了順序則需要比較多的調(diào)試成本。所以由此看出,純粹基于“庫”模式的開發(fā)會帶來很多隱患,這里只提到了開發(fā)過程中常遇到的問題,另外,這種手寫js標(biāo)簽引用js文件的方式也是缺乏語義并犧牲了性能(每個script src占用一個http請求?),同時,inline script block散步在頁面的各個角落,盡管每個script block都被匿名函數(shù)閉包起來,開發(fā)速度很快,但這種代碼毫無結(jié)構(gòu)性可言,對于其他人也是晦澀難懂,等到項目中后期的維護成本會很高,所以說換作誰都不愿意去接手維護一個如此coding的項目。因此,可以認(rèn)為這種coding方式所導(dǎo)致的代碼污染會大大降低生產(chǎn)率(這里的生產(chǎn)率包括開發(fā)和維護兩部分)和頁面性能。

而yui3強制使用Ylaoder,從結(jié)構(gòu)上一定程度的保證代碼質(zhì)量和可讀性。按照yui3的思路,項目的前期應(yīng)當(dāng)花大精力去做模塊的依賴,在此基礎(chǔ)上開發(fā)出豐富的widget,使用過程中指需要load模塊名字,而不必去關(guān)系模塊需要依賴那些js,以及這些js的先后順序是什么。另外,通過簡單hack,loader可以將yui3以及所有項目js都combo在一起(taobao assetcdn現(xiàn)在不提供這種功能,不過很快就會有了),在多的模塊都合并到一個js http請求中,外加一個種子,一個頁面的js http請求頂多只有兩個。

那么是否可以說,象taobao這種復(fù)雜多變(需求變更頻繁)的大網(wǎng)站就可以用yui3來架構(gòu),以避免深度的代碼污染了呢?非也,yui3在設(shè)計上并不能滿足類似taobao的這種門戶。上文提到了網(wǎng)站的四個組成部分,全局、外框、主內(nèi)容區(qū)和組件,他們之間的關(guān)系應(yīng)當(dāng)是什么樣的呢?顯然,頁面rander的時候,應(yīng)當(dāng)首先加載全局變量,然后初始化load頁面所屬于的子站的公共頭和公共尾,之后再執(zhí)行頁面邏輯,因此網(wǎng)站三個層次的邏輯關(guān)系很明確,所以三者之間必然會發(fā)生耦合,框架則需要將這三個層次之間的耦合降到最低,因為,實際情況可能是由很多人同時開發(fā)框架功能、模塊、頁面主邏輯和底層庫的維護,因此就需要每個部分的負(fù)責(zé)團隊的代碼相互隔離,以保證并行開發(fā)中不發(fā)生沖突,鑒于此,純粹基于yui3的代碼結(jié)構(gòu)有三種:

1,通過YUI().use()的嵌套將層次之間的邏輯關(guān)系表達(dá)清楚,比如,a的代碼屬于框架,b的代碼屬于應(yīng)用,c的代碼屬于子應(yīng)用:

YUI().use(*,function(){ //a的代碼 YUI().use(*,function(){ //b的代碼 YUI().use(*,function(){ //c的代碼 }); });});

三個閉包的嵌套,這段代碼層次感比較清晰,把a的代碼看作框架,b的代碼看作應(yīng)用,c的代碼看作子應(yīng)用,調(diào)用關(guān)系一目了然,即框架執(zhí)行完畢后加載并執(zhí)行應(yīng)用的代碼,應(yīng)用的代碼加載并執(zhí)行完后執(zhí)行子應(yīng)用的代碼。

但三段代碼非常緊密的耦合在一塊,在團隊并行開發(fā)中將會經(jīng)常發(fā)生代碼沖突。如果代碼一次編寫不再修改則這種寫法并無大礙,往往代碼需要經(jīng)過反復(fù)修改,因此這種顯示依賴的編碼風(fēng)格無法避免代碼污染的發(fā)生。而且最可能b部分的代碼是污染最嚴(yán)重的,因為應(yīng)用可能包含多個子應(yīng)用,比如產(chǎn)品的列表頁御覽頁和詳情頁可能都包含相同的右側(cè)廣告位,這樣b的代碼中就可能包含有平級的多個YUI().use()。

另外一點,每個YUI().use相當(dāng)于一個loader,每次loader的加載都會將本閉包內(nèi)需要的模塊所對應(yīng)的js文件加載進(jìn)頁面中,這樣如果三次loader的加載有重復(fù)的情況則無法去重,造成的不必要的http請求將會增加一倍以上,嚴(yán)重影響性能。

2,一個閉包,各自入口

YUI().use(/*a,b,c的modules*/,function(){ a.start(); b.start(); c.start();});

這種寫法比較精煉,調(diào)用順序一目了然,同樣,若代碼一次編寫不再修改則這是一種不錯的寫法,考慮到代碼的頻繁修改,這種方法仍有三個缺點,1,a,b,c都各自需要引用各自的modules,各自的模塊是作為參數(shù)寫在use的非倒數(shù)第一個參數(shù)中的,誰也不清楚哪些是a的模塊,哪些是b的模塊,哪些是c的模塊,這種歧異代碼是多人協(xié)作項目中必須要避免的。2,a,b,c的代碼之間看不出依賴關(guān)系,而實際上,框架、應(yīng)用和子應(yīng)用之間的調(diào)用應(yīng)當(dāng)是按順序,而在代碼維護過程中,a,b,c的調(diào)用順序是可能被修改的。3,三個人寫的代碼仍然在一起,不敢保證每次修改都會將模塊封裝致頁面中,一旦有人開了先例圖省事將模塊代碼直接寫在了這個閉包中,以后的修改將會一發(fā)不可收拾,導(dǎo)致每次需求變更都會更加污染代碼。這種情況在雅虎關(guān)系的開發(fā)中頻繁發(fā)生,并最終導(dǎo)致代碼極其臃腫,后期即便開發(fā)一個類似tabnew的小功能都要耗費半個月時間。

3,各自閉包,互不干擾

YUI.use(*,function(Y){ //a的代碼});YUI.use(*,function(Y){ //b的代碼});YUI.use(*,function(Y){ //c的代碼});

三個人寫的代碼完全分開,不存在相互干擾的問題,再者,即便某個人的代碼寫的亂七八糟,也不會影響其它人的代碼的健康。但缺點有2個,1,象上一節(jié)說的代碼實際上有依賴關(guān)系,這里看不出依賴關(guān)系,2,同樣的性能問題。

因此如上所述諸多因為框架約束不足帶來的代碼污染和維護成本增高的現(xiàn)象,應(yīng)當(dāng)通過更加強壯的框架來解決。目前正在開發(fā)中的cubee框架將會很大程度解決上述問題的發(fā)生。

嗯?什么是cubee,cubee有什么用?首先可以確定,cubee是框架,非庫,初衷是解決的是團隊項目中的代碼污染和降低高維護成本,關(guān)于cubee的設(shè)計詳情以后再分享吧。

原文地址:

http://uedmagazine.com/ued/comments.php?y=09&m=09&entry=entry090905-051322

如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答?。?點擊進(jìn)入論壇

發(fā)表評論 (236人查看,0條評論)
請自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動的言論。
昵稱:
最新評論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號