宅男程序員給老婆的計算機課程之6:模版引擎
原創(chuàng)【51CTO獨家特稿】設(shè)計模式再“高級”一點,便是所謂的“框架”了。
從事Web開發(fā),一般都會接觸到MVC框架這個概念。
M:也就是Model,直接跟網(wǎng)站數(shù)據(jù)庫相關(guān)。
V:也就是View,是網(wǎng)頁的模版,跟顯示數(shù)據(jù)相關(guān)。
C:則是Controller,相當于網(wǎng)站的業(yè)務(wù)邏輯。
MVC也不僅僅是應(yīng)用于網(wǎng)站開發(fā),它的概念實際上植根于桌面軟件,并且在手機軟件開發(fā)上也有應(yīng)用。
MVC本身是一個設(shè)計模式,是一個被驗證過的,可以用來很好歸納、管理代碼的軟件開發(fā)方式。
基于這樣的設(shè)計模式,提供了很多相關(guān)的類庫實現(xiàn),則“設(shè)計模式”升級為“框架”。
MVC的任何一個方面,擴展出去講,都可以講上幾天幾夜。
今天只講V。
傳統(tǒng)的ASP / PHP網(wǎng)站開發(fā),V是很混亂的。
默認只有一種文件,html與業(yè)務(wù)邏輯代碼混雜在同一個文件;相當難以維護。
ASP.NET相對于asp做出了很大改進,提出了code-behine的概念:默認將html的模版代碼,以及c#或者vb.net的邏輯代碼切分到兩個不同的文件。
這樣的方式算是有很大進步。
微軟平臺上做開發(fā)是比較苦逼的,微軟掌控了整個開發(fā)平臺的前進速度。
asp跟PHP在開始的時候,是相似的技術(shù)。有類似的便利,以及類似的麻煩。
微軟推出了.net,推廣了code-behind的模式;然后,所有的微軟程序員都超著微軟指定的這個方向去邁進。
asp被拋棄了,自從ASP.NET誕生之后,就不再有任何改進。
而PHP,在開源世界中,則不斷的得到各式各樣的改進。
各種模版引擎層出不窮;不僅可以實現(xiàn)code-behind這樣簡單的模版、業(yè)務(wù)代碼分割;很多還直接引入了MVC的概念;實現(xiàn)了三層的分割。
而ASP.NET,則長期止步于web form的code-behind,在開源世界中的MVC方案大放光彩若干年后,才推出 ASP.NET MVC。
模版技術(shù),最初的目的就是要把業(yè)務(wù)代碼,也就是說,把獲得數(shù)據(jù)的代碼跟html分割。
在模版實現(xiàn)上,因此涌現(xiàn)了不少不同的設(shè)計哲學(xué)。
Python的Django框架中的模版,是一種典型。
它徹底的禁止程序員在模版中嵌入任何代碼;模版中,只可以出現(xiàn)html;以及一些跟業(yè)務(wù)邏輯無關(guān)的控制標簽,如:
- {% If XXXX %} foo {% else %} bar {% end %}
條件XXXX,必須是一個數(shù)據(jù)值,不可以是一個復(fù)雜表達式、不可以包涵函數(shù)調(diào)用等等。
模版中,也不可以聲明任何新的變量,下面的做法是被禁止的:
- {% set i = 0 %}
- {% foreach item in items %}
- {% i += 1%}
- <div>
- {{ item }}
- {% if i mod 2 == 0 %}
- <hr />
- {% end %}
- </div>
- {% next %}
Django的模版,從技術(shù)上徹底禁止程序員添加任何邏輯,強迫程序員必須在controller中去寫各種邏輯,以確保模版內(nèi)容的純潔干凈。
所以Django的模版,一般都非常簡單,有很好的移植性,并且可以讓網(wǎng)頁設(shè)計人員直接編輯。
ASP.NET則是另一種典型;雖然有了code-behind,但是它沒有對前端代碼,以及后端代碼做任何限制。
在前端aspx頁面中,可以嵌入任意的邏輯代碼,而code-behind的code,為空白;這種偽“code-behind”的方式,跟原來的asp沒啥區(qū)別。
ASP.NET從框架本身,并不阻止程序員去做這樣的事情,實際上,它還標榜它這樣的特性:方便原有的asp項目直接升級到.NET的平臺上。
也有另外一種奇葩的做法,前端aspx頁面保持空白,然后在code-behind的code中去拼接所有的html。這樣的方式,ASP.NET框架本身也不禁止。
只要ASP.NET程序員喜歡,沒有什么不可以的。
ASP.NET把對模版使用方式的選擇權(quán)留給了程序員,如果程序員自律,他們可以按Django模版那樣的方式去使用模版,并擁有Django一樣的優(yōu)點;如果程序員自律?!
在某些可以通過嵌入代碼去快速處理的場景,ASP.NET的模版也保留了程序員去hack的能力。
還有一些模版技術(shù),則是折衷的(如tornado的模版):允許嵌入單行代碼,如聲明變量,調(diào)用函數(shù)等等;但是不允許整塊、整塊的業(yè)務(wù)代碼出現(xiàn)模版中。
上述三種模版設(shè)計哲學(xué),各有它們的道理,以及應(yīng)用場景。
需要根據(jù)具體的業(yè)務(wù)、應(yīng)用場景,才能說其中哪種比較合適。
開發(fā)人員的能力也是直接相關(guān)的,如果團隊中,普遍不自律;缺乏將業(yè)務(wù)、模版代碼分割、以提高代碼可維護性的意識,那么Django的做法是最好的,它直接禁止去濫用模版,強迫他們?nèi)ナ褂酶玫拈_發(fā)風格;即便在某些場景下會更麻煩。
武斷的認為任何一種模版設(shè)計哲學(xué)是“最佳”的想法是極其膚淺的。
各種成熟的模版技術(shù),一般也都會有包括以下特性:
1. 嵌入
也就是說,編寫各種可以復(fù)用的小模版塊,然后供多個不同地方調(diào)用;比方說,用戶頭像(甚至名片)的顯示。
具體頁面不需要重復(fù)編寫這些重復(fù)的模塊。
并且,這些模塊需要調(diào)整時,只需要修改一個地方,便可以在所有地方生效。
2. 繼承
能夠編寫一些基礎(chǔ)模版,定義常見的頁面結(jié)構(gòu)。
具體頁面繼承這些基礎(chǔ)模版,便不需要重復(fù)編寫那些結(jié)構(gòu)代碼。
同樣的,當頁面結(jié)構(gòu)需要調(diào)整時,也是修改一處,所有生效。
3. i18n
網(wǎng)頁模版的國際化支持是一個模版引擎是否成熟的表現(xiàn)。
如果沒有,當網(wǎng)站需要同時提供多種不同語言支持的時候,會很麻煩。
成熟的模版,都會提供內(nèi)置的支持。
因為網(wǎng)頁模版實現(xiàn)實在是太多了,大家功能也都差不多,那么性能,也就成為了相當重要的比較指標。
有的模版,能夠“編譯“,渲染起來快些。
一般可以簡單認為,功能越多的模版,性能會約低。有的模版,甚至將i18n的支持變成可配置的,不需要的時候就可以關(guān)閉,以提高性能。
也有的模版認為,寫 {% %} <%%> {{}} 這樣的符號太麻煩了,可以直接忽略,它可以自動聰明的識別 html,以及模版控制代碼。簡單的說,就是以極其華麗的方式,去方面程序員少打幾個字符。
還有的模版,在實現(xiàn)嵌入功能的時候,還可以選擇所依賴的的css / js文件。
比方說,要顯示用戶的名片,需要引入 namecard.css;那么,可以在 namecard的模塊文件中指定這個依賴,然后模版渲染的時候,自動把這個css的引用,放在html的頭部。
直接在模塊文件中寫 namecard.css 的引用是很傻的,因為模塊可以在模版中引用多次。重復(fù)引用同一個css文件是沒有道理的。
種種模版功能細節(jié),實際上,都是可以在沒有模版支持的框架中去實現(xiàn)。
想想PHP,它本來是非常簡單的,默認只能夠在同一個文件中混雜邏輯與代碼。
但一旦程序員有了追求,它也可以有模版實現(xiàn)。
模版不支持 i18n,程序員一般也是有辦法在現(xiàn)有模版實現(xiàn)中添加相應(yīng)的支持的。
并不復(fù)雜,關(guān)鍵是看程序員的態(tài)度;看程序員是否有把事情做得更好、更優(yōu)雅的態(tài)度。
一般情況下,程序員選擇去實現(xiàn)更多的模版功能的時候,必須先看看別人是怎么做的。比方說,如果完全不知道什么是gettext就去自行實現(xiàn)模版的 i18n 功能,是非常2B的。
絕大多數(shù)情況下,程序員面臨的問題,都不是自己獨有的,一定是別人已經(jīng)解決過的問題。
是否有足夠的見識,有足夠的知識廣度,了解別人的解決同樣問題的做法是程序員能力的表現(xiàn)。
是否有快速的搜索出類似的解決方案,也是能力的表現(xiàn)。
1. PHP的Smarty 模版的設(shè)計哲學(xué)是什么?
2. Perl的Mason 模版的設(shè)計哲學(xué)是什么?
3. 什么是gettext?
4. 前端Javascript實現(xiàn)的模版中,目前最成熟的是哪個引擎?
男主角:Wuvist(新浪微博),真名翁偉,自稱胖程序員一個,幸好已婚。學(xué)習.NET
本文作者:Wuvist
女主角:Katze,Wuvist的老婆,女程序員,
51CTO系列: