重構(gòu)后端模板文件的一種實踐

后端的動態(tài)模板

Java后端通常會使用ftl(freemarker template language)模板文件來動態(tài)返回前端頁面。這個工作,通常還可以用jsp烁落、php文件來實現(xiàn)肺孵。但這些動態(tài)模板的實現(xiàn),通常是在已有的html文件上對特定的需要做動態(tài)處理的部分做改寫。這對小項目來講沒什么不對腋舌≡郏可如果你的頁面數(shù)量足夠多,維護(hù)它們將成為一件異常困難的事情蔬蕊。

Nodejs大前端技術(shù)

在目前的大前端技術(shù)棧下结澄,Nodejs的各種框架讓前端開發(fā)變得規(guī)矩不少。我的一個理解是岸夯,傳統(tǒng)前端的html+css+js的技術(shù)棧的最大問題在于其模塊化麻献、組織能力像是一個教學(xué)語言,應(yīng)有的語句控制和代碼復(fù)用的技術(shù)猜扮,都顯得蒼白無力勉吻。

就html的編寫來講,幾乎不存在一種類似函數(shù)的復(fù)用方式旅赢,能夠簡化重復(fù)的UI component的生成餐曼。你只能不斷地去寫一些重復(fù)的、雜亂的代碼鲜漩。整體上來講源譬,這不僅難以做后期的維護(hù),也無法輕易地看懂其間的代碼邏輯孕似。

一句話來講踩娘,這些代碼非常類似于機(jī)器代碼或者匯編代碼。沒有高級語言的精準(zhǔn)控制和抽象層去對代碼做宏觀把控喉祭。

Pugjs是一個很好的html預(yù)處理項目养渴。它的基本想法是:

不要去直接編寫“底層”的html代碼,而是用自己定義的一套語法去編寫pug文件泛烙。

通過這個pug文件去生成出html代碼理卑。特別的,在它的語法中蔽氨,你不必再寫一大堆的尖括號和與前后呼應(yīng)的tag藐唠。如同Python,僅僅依靠代碼的對齊方式鹉究,就可以自動識別相應(yīng)的作用域范圍宇立。例如

<div> 
    <ul>
        <li> First tip </li>
        <li> Second tip </li>
        <li> Third tip </li>
    </ul>
</div>

這樣語義簡單、語法繁瑣的一堆代碼自赔,在pug下可以簡化為

div
    ul
        li First tip
        li Second tip
        li Third tip

但這還不是最誘人的技術(shù)妈嘹,因為這無非是加入了一些語法糖。最為誘人的是pug提供的函數(shù)绍妨,它能夠定義一個函數(shù)去生成某個組件润脸。

例如柬脸,如果你需要定義一組table,每個table僅僅是表頭或者其中一部分的數(shù)據(jù)不一樣毙驯,你該如何處理肖粮?傳統(tǒng)的方式當(dāng)然是復(fù)制粘貼一堆模板代碼,然后一個個地去修改里面的數(shù)據(jù)尔苦。

pug的處理方式就要好太多,完全符合將數(shù)據(jù)和代碼分離的思想行施。定義函數(shù):

mixin leftbox-gen(dataObj)
        table.table
            thead
                tr
                    th(scope="col") #{dataObj.title}
            tbody
                each area in dataObj.areas
                    tr
                        td
                            .box-title #{area.name}
                            ul
                                each subarea in area.subareas
                                    li
                                        a(id=subarea.id, href=subarea.url) #{subarea.name}

這樣就可以根據(jù)通過定義json格式的dataObj去引用函數(shù):

+leftbox-gen(cs_leftbox_data)

你通過不同的json數(shù)據(jù)允坚,就能夠生成不同的table出來。這就實現(xiàn)了代碼的模塊化和以及數(shù)據(jù)和業(yè)務(wù)代碼的分離蛾号。要做出新的table component稠项,你只需要改變數(shù)據(jù)就可以了。

這樣的實現(xiàn)方式在別的高級語言中是很常見的鲜结,但是在傳統(tǒng)的前端代碼中展运,這常常難以見到。原因就在于精刷,html代碼更像是沒有抽象層的機(jī)器代碼拗胜,只是一大堆的實際操作,而缺少抽象層的高效管理怒允。

前端預(yù)處理和后端動態(tài)模板的結(jié)合

pug這樣優(yōu)秀的工具埂软,如果能夠用來管理后端的ftl模板當(dāng)然會相當(dāng)合適。優(yōu)秀的語法糖纫事、代碼模塊化勘畔、數(shù)據(jù)和業(yè)務(wù)邏輯的分離,實在是相當(dāng)誘人的選擇丽惶。

但這樣的理念真要實施在生產(chǎn)代碼中炫七,特別是用來重構(gòu)已有的legacy code時,就不大容易了钾唬。

例如万哪,pug只能生成html代碼,且生成出來的位置通常是在一個統(tǒng)一的地方抡秆∪榔裕可ftl代碼卻分散在各個不同Java工程的不同目錄之下。這兩者很難統(tǒng)一到一起琅轧。

或許一個直接的想法是伍绳,不如直接把所有的ftl都放到一個地方,這樣就不用把模板語言分散到各個不同項目的不同文件夾里乍桂,而難以維護(hù)冲杀。

但這種方案帶來的一個麻煩是效床,如果真的把后端的ftl文件挪動了位置,那么你后端代碼的接口部分就不得不做修改权谁。而這樣的接口部分其數(shù)量并不少剩檀。既要做出大量的修改,還要保證它們的正確性旺芽,并不是一件輕松的事情沪猴。

經(jīng)過大量的思考和嘗試,我得出的一個解決方案是:

使用Pugjs生成出統(tǒng)一的ftl文件采章,放在同一個公共資源文件夾下运嗜。讓每一個具體項目下的ftl文件中,直接include這個公共資源文件夾中ftl內(nèi)容悯舟。

這種做法的一個精妙之處是:它將ftl文件當(dāng)作函數(shù)接口來使用担租。后端Java代碼調(diào)用ftl文件可以看作是函數(shù)調(diào)用。而函數(shù)實現(xiàn)并不需要直接放在這個ftl文件里抵怎,而是可以放在別的地方做引用奋救。這就把實現(xiàn)和調(diào)用部分,通過一個單獨(dú)的文件分離開了反惕。

這里雖然處理的是后端模板文件和前端的一個結(jié)合尝艘,但其思想可以利用在別的地方。如果一個模板文件具備了include功能姿染,便可以把模板文件本身當(dāng)作接口利耍,從而將實現(xiàn)與定義分離。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盔粹,一起剝皮案震驚了整個濱河市隘梨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舷嗡,老刑警劉巖轴猎,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異进萄,居然都是意外死亡捻脖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門中鼠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來可婶,“玉大人,你說我怎么就攤上這事援雇∶剩” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長具温。 經(jīng)常有香客問我蚕涤,道長,這世上最難降的妖魔是什么铣猩? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任揖铜,我火速辦了婚禮,結(jié)果婚禮上达皿,老公的妹妹穿的比我還像新娘天吓。我一直安慰自己,他們只是感情好峦椰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布龄寞。 她就那樣靜靜地躺著,像睡著了一般们何。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上控轿,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天冤竹,我揣著相機(jī)與錄音,去河邊找鬼茬射。 笑死鹦蠕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的在抛。 我是一名探鬼主播钟病,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼刚梭!你這毒婦竟也來了肠阱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤朴读,失蹤者是張志新(化名)和其女友劉穎屹徘,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衅金,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡噪伊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了氮唯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鉴吹。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖惩琉,靈堂內(nèi)的尸體忽然破棺而出豆励,到底是詐尸還是另有隱情,我是刑警寧澤瞒渠,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布肆糕,位于F島的核電站般堆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏诚啃。R本人自食惡果不足惜淮摔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望始赎。 院中可真熱鬧和橙,春花似錦、人聲如沸造垛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽五辽。三九已至办斑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杆逗,已是汗流浹背乡翅。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留罪郊,地道東北人蠕蚜。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像悔橄,于是被迫代替她去往敵國和親靶累。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

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