關(guān)于三種主流WEB架構(gòu)的思考
Haohappy haohappy AT msn.com
轉(zhuǎn)載請(qǐng)注明來源:http://blog.csdn.net/haohappy2004
做WEB好幾年了,各種語言和技術(shù)都稍有涉獵。今天心血來潮,突然想總結(jié)一下。其實(shí)不論什么技術(shù),什么需求,通常WEB開發(fā)就是通過WEB前端管理一個(gè)或大或小或獨(dú)立或分布式的關(guān)系型數(shù)據(jù)庫(kù),很多東西都是相通的。這里說的WEB架構(gòu),是指WEB應(yīng)用開發(fā)中每種技術(shù)獨(dú)有的資源組織形式(包括文件,數(shù)據(jù)庫(kù),HTTP請(qǐng)求處理等。注意并非OO的開發(fā)方式才有架構(gòu)一說),也許說開發(fā)方式更容易讓人理解一些。
以下想法主要以PHP實(shí)現(xiàn)為示例,但很多體會(huì)我想Java,.NET,Ruby開發(fā)者應(yīng)該也很容易理解。最后是我對(duì)于剛面世就引起無數(shù)人關(guān)注的Delphi fo PHP的評(píng)測(cè)。
WEB程序的架構(gòu)基本上可以分成以下三類:
(一) 基于“WEB頁面/文件”,例如CGI和PHP/ASP程序。程序的文件分別存儲(chǔ)在不同的目錄里,與URL相對(duì)應(yīng)。當(dāng)HTTP請(qǐng)求提交至服務(wù)器時(shí),URL直接指向某個(gè)文件,然后由該文件來處理請(qǐng)求,并返回響應(yīng)結(jié)果。
比如http://www.website.conm/news/readnews.php?id=1234
可以想像,我們?cè)谡军c(diǎn)根目錄的news目錄下放置一個(gè)readnews.php文件。
這種開發(fā)方式最自然,最易理解,也是PHP最常用的方式。要注意產(chǎn)生的URL對(duì)搜索引擎不友好,不過你可以用服務(wù)器提供的URL重寫方案來處理,例如Apache的mod_rewrite。
(二) 基于“動(dòng)作”(Action)。這是MVC架構(gòu)的WEB程序所采用的最常見的方式。目前主流的WEB框架像Struts、Webwork(Java),Ruby onRails(Ruby),ZendFramework(PHP)等都采用這種設(shè)計(jì)。URL映射到控制器(controller)和控制器中的動(dòng)作(action),由action來處理請(qǐng)求并輸出響應(yīng)結(jié)果。這種設(shè)計(jì)和上面的基于文件的方式一樣,都是請(qǐng)求/響應(yīng)驅(qū)動(dòng)的方案,離不開HTTP。
比如 http://www.website.com/news/read/id/1234
可以想像在實(shí)際代碼中,我們會(huì)有一個(gè)控制器newsController,其中有一個(gè)readAction。不同框架可能默認(rèn)實(shí)現(xiàn)方式稍有不同,有的是一個(gè)Controller一個(gè)文件,其中有多個(gè)Action,有的是每個(gè)Action一個(gè)文件。當(dāng)然這些你都可以自己控制,題外話。
這種方式的URL通常都很漂亮,對(duì)搜索引擎友好,因?yàn)楹芏嗫蚣芏甲詭в蠻RL重寫功能。可以自由規(guī)定URL中controller、action及參數(shù)出現(xiàn)的位置。
另外,還有更直接的基于URL的設(shè)計(jì)方案,那就是REST。通過人為規(guī)定URL的構(gòu)成形式(比如Action限制成只有幾種)來促進(jìn)網(wǎng)站之間的互相訪問,降低開發(fā)的復(fù)雜性,提高系統(tǒng)的可伸縮性。REST對(duì)于Web Services來說是一個(gè)創(chuàng)新。
雖然本文討論的是單個(gè)項(xiàng)目所采用的架構(gòu),而REST是為了解決網(wǎng)站之間的通訊問題,但REST的出現(xiàn),會(huì)對(duì)單個(gè)項(xiàng)目的架構(gòu)造成影響(很顯然你在開發(fā)時(shí)就要構(gòu)造規(guī)范的URL)。將來混用REST和MVC應(yīng)該也是一種趨勢(shì)。RoR提供很好的REST支持,ZendFramework也提供了Zend_Rest來支持REST,包括Server和Client。
(三) 基于“組件”(Component ,GUI設(shè)計(jì)也常稱控件)、事件驅(qū)動(dòng)的架構(gòu),最常見的是微軟的.NET。基本思想是把程序分成很多組件,每個(gè)組件都可以觸發(fā)事件,調(diào)用特定的事件處理器來處理(比如在一個(gè)HTML按鈕上設(shè)置onClick事件鏈接到一個(gè)PHP函數(shù))。這種設(shè)計(jì)遠(yuǎn)離HTTP,HTTP請(qǐng)求完全抽象,映射到一個(gè)事件。
事實(shí)上這種設(shè)計(jì)原本最常應(yīng)用于傳統(tǒng)桌面GUI程序的開發(fā),例如Delphi,Java Swing等。所有表現(xiàn)層的組件比如窗口,或者HTML表單都可以由IDE來提供,我們只需要在IDE里點(diǎn)擊或拖動(dòng)鼠標(biāo)就能夠自動(dòng)添加一個(gè)組件,并且添加一個(gè)相應(yīng)的事件處理器。
這種開發(fā)方式有幾個(gè)優(yōu)點(diǎn):
· 復(fù)用性 -代碼高度可重用。
· 易于使用 -通常只需要配置控件的屬性,編寫相關(guān)的事件處理函數(shù)。
我個(gè)人也挺喜歡這種方式,PEAR就提供了相當(dāng)強(qiáng)大的HTML_QuickForm,用于在頁面添加表單元素及其事件處理函數(shù),還可以與Smarty等模板引擎相結(jié)合。這對(duì)于項(xiàng)目開發(fā)來說是一個(gè)補(bǔ)充性的功能,在項(xiàng)目中的某些部份使用QuickForm,有時(shí)可以大大加快開發(fā)。
而完全基于組件和事件驅(qū)動(dòng)的開發(fā)框架對(duì)于PHP來說也已經(jīng)不新鮮,PRADO就是一個(gè)這樣的框架,曾經(jīng)得過Zend編程大賽的頭獎(jiǎng)。但目前來說很顯然Prado所提倡的這種開發(fā)方式仍然沒有被大部份PHP程序員所接受。為什么呢?
我覺得主要有以下兩個(gè)問題:
(1)效率問題
這里指的不是開發(fā)效率,而是代碼的執(zhí)行效率。眾所周知,正常情況下,PHP的執(zhí)行是相當(dāng)高效的。但是目前這種基于控件的框架效率都成問題。Prado本身提供了一個(gè)緩存機(jī)制來緩解這個(gè)問題。如果不采用緩存,可以說很多站點(diǎn)根本不能使用Prado這樣的框架,比如門戶網(wǎng)站,大型論壇等。
但ASP .NET不太一樣,因?yàn)樗蔷幾g型的框架,最后生成的代碼是編譯生成的,不需要再次進(jìn)行中間過程的諸多處理,所以在第一次執(zhí)行之后速度會(huì)很快,執(zhí)行效率還是很高的?!∵@是語言層次的功能,Prado無法通過代碼層次的努力完全彌補(bǔ)。
(2)沒有強(qiáng)大的IDE支持
設(shè)置控件的屬性,添加其對(duì)應(yīng)的事件處理器,看似簡(jiǎn)單,但控件多了,這也是個(gè)繁重的工作。.NET的強(qiáng)大就在于它把程序員從重復(fù)的工作中解放了出來,設(shè)置屬性很方便,事件處理器也會(huì)自動(dòng)添加。Prado目前沒有這樣的IDE支持。
總之,這種基于控件的框架比較適合于用戶交互較多的,需要對(duì)頁面中的很多組件設(shè)置不同處理操作,但對(duì)于性能要求不高的應(yīng)用。另外,帶有組件支持的框架通常對(duì)AJAX的支持都較好,比如.NET和Ruby on Rails。
綜上,三種架構(gòu)基本上可以代表目前的所有主流WEB開發(fā)方式,包括PHP,JavaEE,.NET,Ruby/RoR。
目前PHP開發(fā)的狀況和未來的趨勢(shì):
平時(shí)做PHP比較多,特別總結(jié)一下PHP開發(fā)的趨勢(shì)。目前在PHP開發(fā)中,我們最常用的是基于“文件”的架構(gòu),其實(shí)也就是一種“面向過程”的開發(fā)方式。通常我們寫PHP程序的目的就是“快點(diǎn)上線,讓程序跑起來”。而且大多數(shù)PHP程序員還要和HTML、CSS做近身搏斗,所以如果程序太抽象,調(diào)整視覺效果就比較困難。所以對(duì)于小項(xiàng)目,這是一個(gè)最好的選擇。
但越來越多人認(rèn)識(shí)到,面向?qū)ο蠛蚆VC框架更能促進(jìn)代碼的復(fù)用和分享,而且程序易于擴(kuò)展,隨著程序復(fù)雜性的增加這個(gè)趨勢(shì)越明顯。所以O(shè)O框架層出不窮。目前PHP框架當(dāng)中最有前景的是CakePHP、Symphony和ZendFramework,各自擁有活躍的社區(qū)和龐大的用戶群,都在快速成長(zhǎng)當(dāng)中。PHP的框架都避免走Java框架龐大臃腫的老路,致力于快速開發(fā),而且主動(dòng)模仿和吸收RoR這些優(yōu)秀框架的新特性。隨著PHP5的普及和這些框架的成熟,加上PHP原本開發(fā)社區(qū)的龐大人數(shù),將來也許又會(huì)再產(chǎn)生出一些行業(yè)性的標(biāo)準(zhǔn)。
這種選擇適合于中大型項(xiàng)目,特別是需要較大的團(tuán)隊(duì)合作和需要長(zhǎng)期維護(hù)和二次開發(fā)情況。個(gè)人認(rèn)為這是將來PHP開發(fā)的趨勢(shì)。
而對(duì)于基于組件和事件驅(qū)動(dòng)的開發(fā)方式大多數(shù)PHP程序員都不感興趣。但是也有不少人在做這方面的努力,例如Codegear的Delphi for PHP,就吸引了很多人的關(guān)注。如果有強(qiáng)大的商業(yè)支持,也許將來在開發(fā)市場(chǎng)也會(huì)占一席之地。
我會(huì)在下一篇文章介紹D4P的新特性并作評(píng)測(cè)。
WEB開發(fā)的未來展望:
隨著更貼近HTTP的REST的流行,我覺得像.NET和Java中的抽象組件的方式會(huì)受到?jīng)_擊。因?yàn)檫@些組件并不如它們所承諾的那么方便。未來MVC+REST+RIA的模式應(yīng)該會(huì)比較流行。
AJAX是一把雙刃劍,盡管事件驅(qū)動(dòng)的架構(gòu)看起來非常適合于處理異步的請(qǐng)求(可以想像頁面中存在幾個(gè)組件,每個(gè)組件都可以觸發(fā)異步請(qǐng)求,對(duì)應(yīng)對(duì)服務(wù)器端的某個(gè)事件處理器,看起來是很理想的一個(gè)處理方式),但要為客戶端自動(dòng)生成良好的JavaScript代碼是很不容易的,要滿足各種瀏覽器的兼容性要求,還要能夠自己進(jìn)行擴(kuò)展,以滿足項(xiàng)目中千奇百怪的需求。很多時(shí)候我更傾向于使用一些JS框架如Prototype來自己開發(fā)各種效果,而不是在服務(wù)器端生成。在服務(wù)器端生成JS的兩個(gè)結(jié)果,一是對(duì)生成的代碼不信任,二是人變傻,因?yàn)槟悴⒉恢勒嬲l(fā)生了什么。
(一點(diǎn)牢騷也貼上來)
關(guān)于WEB開發(fā)的個(gè)人疑惑:
l 為了讓開發(fā)更簡(jiǎn)單,我們不得不學(xué)習(xí)使用復(fù)雜的開發(fā)工具和框架,這到底是一個(gè)進(jìn)步,還是退步?
l IDE讓程序員變聰明還是變傻? 當(dāng)我們?cè)诜?wù)器代碼里面就可以設(shè)計(jì)客戶端界面,這是一個(gè)進(jìn)步還是退步?
舉個(gè)例子說,微軟的ASP.NETAJAX,讓我們可以在服務(wù)器端設(shè)計(jì)各種異步的控件。那么程序員甚至可以不會(huì)Javascript,不懂AJAX就設(shè)計(jì)出各種客戶端效果。要是哪一天項(xiàng)目需要設(shè)計(jì)稍復(fù)雜的效果,靠IDE和框架無法自動(dòng)完成,你要怎么辦? 到這個(gè)時(shí)候再來學(xué)JS,也許就遲了。更可怕的是,技術(shù)在更新和淘汰,可能十年之后,你會(huì)發(fā)現(xiàn)自己除了各種IDE之后,真正精通的技術(shù)很少,脫離了IDE你寫一個(gè)小程序都要查半天API手冊(cè),因?yàn)槟闫綍r(shí)都是依賴“自動(dòng)補(bǔ)齊”來寫代碼的!這樣的情景,我想沒有人愿意發(fā)生。
也許對(duì)于短期開發(fā)的項(xiàng)目來說,是一個(gè)進(jìn)步,但對(duì)于程序員個(gè)人的成長(zhǎng)來說,這并不是好事。對(duì)工具的依賴,導(dǎo)致了我們對(duì)于底層和核心技術(shù)的不求甚解,限制了個(gè)人的成長(zhǎng)。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1586750
聯(lián)系客服