
MVC 就是把「資料」「畫面」「流程控制」拆開來,讓每個人只管自己的事。聽起來很基本,但你知道有多少專案是把三件事全部塞在同一個檔案裡嗎?
先講結論
MVC 的核心精神是關注點分離。Model 管資料和商業邏輯、View 管使用者介面、Controller 管流程協調。這個架構模式從 1970 年代就存在了,到今天它的變體(MVP、MVVM、Flux)仍然在主宰軟體開發。不是因為它完美,而是因為「把職責拆開」這件事本身就是對的。
用餐廳來理解 MVC
走進一間餐廳:菜單(View) 是你看到的東西,廚房(Model) 負責食材和料理邏輯,服務生(Controller) 接收你的點單、把需求傳給廚房、再把做好的菜端到你面前。
你不會自己跑進廚房炒菜,廚房也不需要知道菜單長什麼樣——每個角色各司其職。
使用者 ──請求──> Controller ──操作──> Model
↑ │
└────回應──── View <──取得資料────────┘
實際的 code 長怎樣
以 Express.js 為例:
Model(處理資料)
// models/user.js
export const User = {
async findById(id) {
return db.query('SELECT * FROM users WHERE id = ?', [id]);
},
async create({ name, email }) {
return db.query('INSERT INTO users (name, email) VALUES (?, ?)', [name, email]);
},
};Controller(處理流程)
// controllers/userController.js
export const userController = {
async show(req, res) {
const user = await User.findById(req.params.id);
if (!user) return res.status(404).render('error', { message: '找不到' });
res.render('user/show', { user });
},
async create(req, res) {
if (!req.body.name || !req.body.email) {
return res.status(400).render('user/new', { error: '請填完' });
}
const user = await User.create(req.body);
res.redirect(`/users/${user.id}`);
},
};View(顯示畫面)
<!-- views/user/show.ejs -->
<h1><%= user.name %></h1>
<p>Email: <%= user.email %></p>看到了嗎?Model 不知道畫面長什麼樣,View 不知道資料從哪來,Controller 負責把兩邊串起來。改 UI 不影響商業邏輯,改資料庫不影響畫面——這就是關注點分離的好處。
MVC 的真正問題:Fat Controller
理論講起來很美好,但實務上最常見的問題是 Controller 越長越肥。驗證邏輯放 Controller、商業規則放 Controller、權限檢查放 Controller、email 通知放 Controller——最後 Controller 變成一個什麼都管的巨獸。
解法?加一層 Service Layer:
// Controller 只負責接收和回應
async create(req, res) {
const result = await userService.register(req.body);
if (result.error) return res.status(400).json({ error: result.error });
res.status(201).json(result.user);
}把商業邏輯抽到 Service,Controller 回歸它的本分:接收請求、呼叫 Service、回傳結果。
Web MVC 不是原本的 MVC
一個你可能不知道的事:現在 Web 框架裡的 MVC 跟 1970 年代 Smalltalk 的 MVC 其實不太一樣。
原始 MVC 裡,View 會直接監聽 Model 的變化(Observer Pattern),Controller 只處理使用者輸入。但 Web 是 Request-Response 模式——使用者發請求、伺服器回應、結束——不存在「View 持續監聽 Model」這回事。
所以嚴格來說,Web MVC 是一個「借用 MVC 精神但實作不同」的變體。不過名字已經叫習慣了,大家也就不計較了。
現代框架已經超越 MVC
React、Vue 這些框架用的是 Component-based 架構——View 和部分邏輯合在元件中,狀態用 Redux / Pinia 管理,API 前後端分離。已經不是傳統 MVC 了。
但 MVC 的核心精神——關注點分離——依然活著。不管架構怎麼演進,「把不同職責拆開」這個原則不會過時。
| 模式 | 說明 | 常見框架 |
|---|---|---|
| MVC | 經典 | Rails, Laravel, Spring MVC |
| MVP | Presenter 取代 Controller | Android(早期) |
| MVVM | ViewModel 與 View 雙向綁定 | Vue.js, Angular |
| Flux/Redux | 單向資料流 | React + Redux |
MVC 不是銀彈,但它教會了我們一件事:把東西拆開來管,永遠比全部混在一起好。
延伸閱讀
MVC是一個巨大誤會 跟著小明一起搞懂技術名詞:MVC、SPA 與 SSR 架構 後端 MVP 設計原則 前端 MVP 設計原則