iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
Modern Web

前端技能樹的十萬個為什麼系列 第 3

Day 3 - 為什麼要用 MVC

  • 分享至 

  • xImage
  •  

前言

由於昨天討論 jQuery 的時候,一再強調 jQuery 不適合龐大、複雜的程式架構,因為直接操作 DOM 去修改畫面,複雜度很容易隨著程式碼行數指數成長。

那隨著時代演進,那些厲害的 SaaS 軟體服務,都一個比一個還複雜,總不可能還在用 jQuery 吧?究竟有什麼辦法呢?

今天要來探討的是 MVC(Model-View-Controller) 程式架構模式

先想一下

  • MVC 是在什麼樣的時代誕生的?
  • MVC 怎麼解決問題?
  • MVC 的優缺點是什麼?
  • MVC 適合什麼情境?

MVC 是在什麼樣的時代誕生的?

MVC 模式雖然早在 1978 年就被提出了,比 jQuery 還早,但若要論及在 JavaScript 前端的應用,卻是晚了許多。

畢竟在 jQuery 稱霸的時代,大家會自然而然把寫程式的重點放在 event-driven(事件驅動),而不是 data-driven(資料驅動),因此在這個習慣下,較容易寫出資料邏輯與畫面邏輯混雜的程式

原則上能跑的程式都是對的程式(?),但論及可維護性、可擴充性、可重構性,往往這樣混雜的邏輯會是一大阻礙。

MVC 怎麼解決問題?

關注點分離

MVC 不是一個技術、library 或 framework,它是一種「軟體架構模式」,換句話說,只要你的程式是按照這個「模式」下去寫的,就算是在用它了。

介紹 MVC 之前,要先來看一個原則叫做「關注點分離」(Separation of concerns,SoC)

由於關注點混雜在一起會導致複雜性大大增加,所以把不同的關注點分離開來,分別處理。

開餐廳的例子

舉例來說,就像是要開一間餐廳,我們需要哪些東西?

廚師、會計師、服務生、櫃檯人員、清潔人員、運送物流...
食材、貨車、記帳本、抹布、筆、點菜單、桌椅...

開一間餐廳這麼多東西,如果全部攪在一起,光用想的就想不開了不想開了。

但如果我們運用關注點分離,概略分為三大類:

  • 後勤層級:負責配送食材、料理食物、會計記帳等,客人看不到的背景作業
  • 服務層級:負責帶位,將料理端給客人,清理桌面等
  • 櫃台層級:負責處理「服務層級」帶過來的客人,點單、結帳等,並交給「後勤層級」

注意到這沒有標準答案,每個人面對同一個議題(例如:開一間餐廳),可以不同原則與分類方式來運用關注點分離,上面分成三大類也只是我的分類角度,你可以分四類五類,或者乾脆兩類(一個前台一個後台)。

但不管你怎麼分,反正肯定是有分類,分類的目的在於聚焦,每個層級都聚焦在自己該做的事情,就不會像義大利麵一樣攪在一起了,而這就是 MVC 的基礎。

MVC 的切分方式

面對一整包龐大、複雜的應用程式,我們也可以根據上述的作法,分成三大類:

MVC

  • Model:負責管理資料結構、資料儲存與讀取等
  • View:負責使用者介面與呈現
  • Controller:負責做為 Model 與 View 的連接橋樑,處理業務邏輯與路由

我盡量讓餐廳的比喻能夠貼近 MVC:後勤(M)、服務(V)、櫃台(C),但細節上肯定還是無法完全類比,如果大家有更好的比喻幫助理解,歡迎留言一起集思廣益!

MVC 的具體範例

我第一次聽到 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 的優缺點是什麼?

優點

  • 各層級各自專注,較容易維護,要改資料就找 Model,要改畫面就找 View
  • 因為程式邏輯切開了,所以容易測試,甚至擴充
  • 可重用性高,同樣的資料 Model,可以給不同的 View 使用

缺點

  • 學習曲線較高,需要以「架構導向」的思維來思考程式的設計,一般新手較難從「大雜燴」思維,轉移到「架構思維」
  • 對於小規模程式架構來說,麻煩度較高,即便是臨時的緊急需求,也要照著 MVC 架構放你的程式,但反過來說,這也是保護程式未來減少 bug 的方式

MVC 適合什麼情境?

大規模、多層級、高複雜度的程式,MVC 到頭來只是一種概念,背後的原理就是關注點分離,事實上,還有 MVP、MVVM 等概念,也是類似的事情,只是分類與切割的方式不同,就跟上面那個開餐廳的例子一樣。

或許有人想說,如果現在才剛要開始一個新專案,規模很小,應該沒必要用到這麼複雜的 MVC pattern 吧?

一方面是,義大利麵不是一開始就是攪拌成一團的......,肯定是經過不斷維護與擴充,才慢慢變得複雜的,若從小規模就先採用 MVC,未來成長到中大規模也不擔心。

另一方面,即便是小規模的專案,現在各種框架崛起,多種 starter kit 簡單好上手,基本的 template 都可以一鍵生成了,MVC 的成本其實愈來愈低了。

結語

心智圖放大版

研究 MVC 這個主題,是一個很有趣的漸進過程,因為我很早就知道 MVC,也很早就試圖搞懂它,但也不是說搞不定,就總有一種「一知半解」的感覺,每次都是慢慢推進對於 MVC 的理解。

直到今天實際把它寫成文章,嘗試用一些比喻來驗證自己的理解,才發現自己心中這張地圖東缺西殘,趕緊找資料,才慢慢圓了這一塊的知識。

但有趣的是,查資料的過程中會發現,好不容易填補了一個坑,卻發現

啊~原來還有更多坑啊!

於是繼續無限補坑...這就是學習的必經過程吧哈哈哈哈哈嗚嗚~

參考資料

維基百科
前端食堂
IT人


上一篇
Day 2 - 為什麼要用 jQuery
下一篇
Day 4 - 為什麼要用 Framework(框架)
系列文
前端技能樹的十萬個為什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
justicebai
iT邦新手 5 級 ‧ 2022-11-15 11:53:56

讚讚!!

我要留言

立即登入留言