由於昨天討論 jQuery 的時候,一再強調 jQuery 不適合龐大、複雜的程式架構,因為直接操作 DOM 去修改畫面,複雜度很容易隨著程式碼行數指數成長。
那隨著時代演進,那些厲害的 SaaS 軟體服務,都一個比一個還複雜,總不可能還在用 jQuery 吧?究竟有什麼辦法呢?
今天要來探討的是 MVC(Model-View-Controller) 程式架構模式。
MVC 模式雖然早在 1978 年就被提出了,比 jQuery 還早,但若要論及在 JavaScript 前端的應用,卻是晚了許多。
畢竟在 jQuery 稱霸的時代,大家會自然而然把寫程式的重點放在 event-driven(事件驅動),而不是 data-driven(資料驅動),因此在這個習慣下,較容易寫出資料邏輯與畫面邏輯混雜的程式。
原則上能跑的程式都是對的程式(?),但論及可維護性、可擴充性、可重構性,往往這樣混雜的邏輯會是一大阻礙。
MVC 不是一個技術、library 或 framework,它是一種「軟體架構模式」,換句話說,只要你的程式是按照這個「模式」下去寫的,就算是在用它了。
介紹 MVC 之前,要先來看一個原則叫做「關注點分離」(Separation of concerns,SoC)
由於關注點混雜在一起會導致複雜性大大增加,所以把不同的關注點分離開來,分別處理。
舉例來說,就像是要開一間餐廳,我們需要哪些東西?
廚師、會計師、服務生、櫃檯人員、清潔人員、運送物流...
食材、貨車、記帳本、抹布、筆、點菜單、桌椅...
開一間餐廳這麼多東西,如果全部攪在一起,光用想的就想不開了不想開了。
但如果我們運用關注點分離,概略分為三大類:
注意到這沒有標準答案,每個人面對同一個議題(例如:開一間餐廳),可以不同原則與分類方式來運用關注點分離,上面分成三大類也只是我的分類角度,你可以分四類五類,或者乾脆兩類(一個前台一個後台)。
但不管你怎麼分,反正肯定是有分類,分類的目的在於聚焦,每個層級都聚焦在自己該做的事情,就不會像義大利麵一樣攪在一起了,而這就是 MVC 的基礎。
面對一整包龐大、複雜的應用程式,我們也可以根據上述的作法,分成三大類:
我盡量讓餐廳的比喻能夠貼近 MVC:後勤(
M
)、服務(V
)、櫃台(C
),但細節上肯定還是無法完全類比,如果大家有更好的比喻幫助理解,歡迎留言一起集思廣益!
我第一次聽到 MVC 時,聽起來非常高大上,又是關注點分離,又是程式架構模式,MVC 各層描述得好像也沒有一定要怎樣,但感覺就可以做到很厲害的事,讓人一知半解。
後來看到維基百科的這個範例,用簡短五行 code,就表示了一個完整的 MVC 架構,讓我瞬間有一種豁然開朗的感覺!
/** 模擬 Model, View, Controller */
var M = {}, V = {}, C = {};
/** Model 負責存放資料 */
M.data = "hello world";
/** View 負責將資料輸出給使用者 */
V.render = (M) => { alert(M.data); }
/** Controller 作為連接 M 和 V 的橋樑 */
C.handleOnload = () => { V.render(M); }
/** 在網頁讀取的時候呼叫 Controller */
window.onload = C.handleOnload;
如果上面的 code 有點難理解,其實我也可以一行就寫出一模一樣的效果:
window.onload = () => { alert("hello world"); };
是不是好理解多了XD?
但顯然這不是 MVC 所期待的,以上兩個範例對比之下,就能夠很輕易理解,為什麼比起 MVC 這種高度抽象化的作法,新手更傾向用「大雜燴」的程式寫法,因為後者顯然(在程式規模不大的情況下)更好理解。
同時,在我看完範例之後,當下真的是有一種又好氣又好笑的感覺
原來 Model 沒有一定要有 DB
原來alert
也算是一種 View
原來 Controller 可以不用這麼複雜
最重要的是
原來 MVC 離我們這麼近 ((廣告嫌疑
大規模、多層級、高複雜度的程式,MVC 到頭來只是一種概念,背後的原理就是關注點分離,事實上,還有 MVP、MVVM 等概念,也是類似的事情,只是分類與切割的方式不同,就跟上面那個開餐廳的例子一樣。
或許有人想說,如果現在才剛要開始一個新專案,規模很小,應該沒必要用到這麼複雜的 MVC pattern 吧?
一方面是,義大利麵不是一開始就是攪拌成一團的......,肯定是經過不斷維護與擴充,才慢慢變得複雜的,若從小規模就先採用 MVC,未來成長到中大規模也不擔心。
另一方面,即便是小規模的專案,現在各種框架崛起,多種 starter kit 簡單好上手,基本的 template 都可以一鍵生成了,MVC 的成本其實愈來愈低了。
研究 MVC 這個主題,是一個很有趣的漸進過程,因為我很早就知道 MVC,也很早就試圖搞懂它,但也不是說搞不定,就總有一種「一知半解」的感覺,每次都是慢慢推進對於 MVC 的理解。
直到今天實際把它寫成文章,嘗試用一些比喻來驗證自己的理解,才發現自己心中這張地圖東缺西殘,趕緊找資料,才慢慢圓了這一塊的知識。
但有趣的是,查資料的過程中會發現,好不容易填補了一個坑,卻發現
啊~原來還有更多坑啊!
於是繼續無限補坑...這就是學習的必經過程吧哈哈哈哈哈嗚嗚~