後端工程師的第一堂課 (19) : 現代系統架構 — MVC

Johnliutw
JohnLiu 的軟體工程思維
6 min readSep 18, 2022

--

這是篇共 30 篇的後端領域入門系列文章,預計 1 -2 週新增 1 個新文章。
在後端領域有許多資源在告訴我們怎麼寫好 Python, Golang, Java, PHP … 等各種程式語言。但卻很少告訴我們怎麼學會 Web 後端領域 的知識。

希望你可以透過這篇文章,搭配你正熟悉中的某門任何程式語言,讓你順利入門 Web 後端 :)

【後端工程師的第一堂課】全系列: https://medium.com/@johnliutw/list/da301cc31b15

MVC,如果你開始學任何程式語言,或是網頁後端工程,則幾乎都會碰到的一個技術名詞。

街頭上有一大堆實踐 MVC 的 Web 框架,丟 Google 也會查到許多 MVC 的介紹以及討論,相信有些讀者也對 MVC 有一些基礎認識,那 MVC 到底是什麼呢?

由於 MVC 有一些定義的爭論,因此這篇的結論,主要是參考不同說法後,以及根據過去開發的經驗觀察歸納後,提供做分享。

什麼是 MVC ?

MVC 是一種 網站開發架構 的設計模式。在一般網站的開發過程中,如果沒有任何的架構,而是需求要什麼就寫什麼,設計畫什麼圖就開發什麼,到最後,會留下一堆所謂的技術債,讓未來每次的更動,都要花更久的時間完成,或是有很多隱藏的 Bug ,都是非常可怕、傷害品質的東西。

而 MVC 就是設定一個基礎的系統架構,未來每個開發者就依循這個架構去開發,雖然淺扯到的區塊可能比較多,但長期來看,維護性更佳,且能讓程式碼的 分工權責 更加明確。

MVC 可以被分成三塊: Model、View、Controller
他們之間的關係和流程就像這張圖:

接下來我們會一一介紹,這三塊分別代表什麼意義!

View

view,是所謂的樣板、模板,在網站裡常常以一般人常見的 HTML 方式撰寫,寫起來就會像這樣:

view 的任務,就是 顯示畫面給使用者,一個網站會有一大堆的 view,畢竟常規上來說,幾乎就是一個網頁,就會有一個 view 的檔案。

上面的程式碼中,顯示了兩筆資料給使用者看,但是通常我們不會把程式碼寫的那麼僵硬,而是會搭配後端 API ,或是程式語言的 HTML 模板產生引擎,例如這是一個 PHP + Laravel 的版本:

Python + Flask 的版本則可以像是:

notifications 是一個陣列,裡面裝有所有的 notification 資料,這其實就是一個另類的 迴圈 ,用來一筆一筆撈出 notifications 裡面所有的資料。

而一些文法像是 {%{{ 則會根據不同語言的 HTML 產生引擎會有所不同,因此我們要理解的是大致結構即可。

通常 view 上會用到的這些資料會來自 controller 層 ,因此 view 會根據 controller 指定要給予的資料,來顯示 HTML。假設是透過後端 API 產生的資料,則通常會用 AJAX 技術,透過 Javascript 來從伺服器拿取資料:

這部分就是另外一個議題,且甚至會用一些前端框架取代 View 的角色,就不在此贅述。

Controller

Controller,它的任務是處理使用者的請求,確定要讀取哪些資料,做好運算,並找出確定要用的 view 檔案 ; 或是像是一個 API Server,只輸出資料,沒有 view。

一個典型 controller 程式如下,以 PHP 做示範:

各位可以觀察到 getNotifications()這個函式中,$notifications就是上面 view 用到的資料來源,該資料需要在 controller 裡面設定好,才能顯示在 view 中。

而這個 function 我們通常會稱呼為 action,是給 view 使用的一個資料來源點,並且可以指定說,運算的結果要顯示在哪一個 view 檔案裡面。

再者,如果我們的這個 action 想像 純API 一樣,也可以只把資料輸出為 json 格式,並產生類似如下的結果

因此 controller 的任務是比較架構性規畫性,著重在商業邏輯的設計,以及資料的獲取。

Model

什麼是 Model ? Model 我們會當作資料的容器,不是指資料庫,是兩個完全不同的概念,要切的非常清楚喔!

我們程式會從資料庫取出資料,並放在 Model 內,讓 Controller 可以使用,因此 Model 內裝資料的欄位,和資料庫的欄位 不一定完全吻合。

雖然在大部分的程式語言和框架,都會假設 Model 內的欄位會和資料庫的欄位相同,不過有時候,仍可能會針對欄位內的資料做 預處理

例如,資料庫裡某筆資料的價格欄位是 100 塊,然後 以美金計價,但是我們網站要根據不同語系,轉換幣種,台幣如果還是顯示 100 塊,會發生被刷單刷爆然後上 Ptt,記者再來抄新聞之類的…

因此我們可以設計一個 model 的功能,會在取出資料時,預先把價格先乘上台幣的匯率,之後在每次操作時都會拿到屬於該幣種的資料,這才是 Model 真正的任務: 定義資料的內容

而程式裡的 Model 通常會和資料庫欄位同名,只是使用大寫開頭,並用單數命名方式。

假設內容什麼都不寫,通常就是預設按照資料庫欄位的資料處理。使用方法則可以在 controller 內直接呼叫 Model :

這就是 model 的一個經典用法,對一個 Notification 的 model 物件呼叫 all 這個函式,可以直接從資料庫中撈取所有的 notifications 資料,而不用寫出完整的 SQL 語句,是不是很方便呢!

--

--

Johnliutw
JohnLiu 的軟體工程思維

熱愛軟體全端技術開發,較為擅長 Web 領域,並有多年線上與線下授課經驗,專精軟體新手教學。 相關合作: johnliutw@hotmail.com