MVC 架構和框架
MVC 架構讓複雜應用的開發過程變得更易於管理,它允許多個開發者協同開發。
第一次瞭解 MVC 模式時,我被這些術語嚇到了,當我實際運用這些概念時更是如此。
回過頭去,理解了 MVC 的含義以及作用,就能更輕鬆地將它運用於 web 應用的開發。
什麼是 MVC
MVC,即 model-view-controller,其中每個組件的含義如下:
-
模型(Model):後端,包含了所有數據邏輯
-
視圖(View):前端界面或 GUI
-
控制器(Controller):應用的大腦,控制數據如何展示
MVC 的概念最早由 Trygve Reenskaug 提出,他提出將其作爲一種開發桌面應用 GUI 的方式。
如今 MVC 被用於現代 web 應用開發,因爲它增強了應用的靈活性、可維護性和可擴展性。
爲什麼要用 MVC?
五個字:關注點分離(separation of concerns,縮寫爲 SoC)。
MVC 模式有助於將前端和後端代碼拆分爲獨立的組件,這樣更便於管理,而且能夠更方便地改動其中的某一部分而不會互相影響。
不過說起來容易做起來難,尤其是多個開發者同時更新、修改或調試一個成熟應用時。
如何使用 MVC
爲了更好地說明 MVC 模式,我引入了一個 web 應用,它展示了這些概念是如何工作的。
我的 Car Clicker 應用是著名的 Cat Clicker 應用的變體。
我的應用主要有以下區別:
-
沒有貓咪,只有性能車的圖片(對不住了,愛貓人士!)
-
列出了多種車型
-
有多個點擊計數器
-
只展示選中的車
讓我們深入瞭解一下構成 MVC 架構模式的三個組件。
模型(數據)
模型的任務是管理數據。不論數據是來自數據庫、API 還是 JSON 對象,模型都要負責管理它們。
在 Car Clicker 應用中,模型對象包含一個由 car 對象組成的數組,其中含有這個應用所需的所有信息(數據)。
它還通過一個初始值爲 null
的變量 currentCar
控制當前展示哪個汽車。
const model = {
currentCar: null,
cars: [
{
clickCount: 0,
name: 'Coupe Maserati',
imgSrc: 'img/black-convertible-coupe.jpg',
},
{
clickCount: 0,
name: 'Camaro SS 1LE',
imgSrc: 'img/chevrolet-camaro.jpg',
},
{
clickCount: 0,
name: 'Dodger Charger 1970',
imgSrc: 'img/dodge-charger.jpg',
},
{
clickCount: 0,
name: 'Ford Mustang 1966',
imgSrc: 'img/ford-mustang.jpg',
},
{
clickCount: 0,
name: '190 SL Roadster 1962',
imgSrc: 'img/mercedes-benz.jpg',
},
],
};
視圖(UI)
視圖決定了用戶看到的內容以及交互方式。
Car Clicker 應用有兩個視圖:carListView
和 CarView
。
每個視圖都有兩個關鍵函數,定義其如何初始化及如何渲染。
這些函數決定了用戶將會看到的內容以及交互方式。
carListView
const carListView = {
init() {
// 保存 DOM 元素,方便後續訪問
this.carListElem = document.getElementById('car-list');
// 渲染視圖(使用正確的數據更新 DOM 元素)
this.render();
},
render() {
let car;
let elem;
let i;
// 從控制器中獲取待展示的汽車
const cars = controller.getCars();
// 確保渲染前列表是空的
this.carListElem.innerHTML = '';
// 遍歷 cars 數組
for(let i = 0; i < cars.length; i++) {
// 當前遍歷到的車
car = cars[i];
// 創建一個汽車列表項(<li>)並設置其文本
elem = document.createElement('li');
elem.className = 'list-group-item d-flex justify-content-between lh-condensed';
elem.style.cursor = 'pointer';
elem.textContent = car.name;
elem.addEventListener(
'click',
(function(carCopy) {
return function() {
controller.setCurrentCar(carCopy);
carView.render();
};
})(car)
);
// 最後將其加入列表
this.carListElem.appendChild(elem);
}
},
};
CarView
const carView = {
init() {
// 保存 DOM 元素指針,方便後續訪問
this.carElem = document.getElementById('car');
this.carNameElem = document.getElementById('car-name');
this.carImageElem = document.getElementById('car-img');
this.countElem = document.getElementById('car-count');
this.elCount = document.getElementById('elCount');
// 點擊時增加當前汽車的計數
this.carImageElem.addEventListener('click', this.handleClick);
// 渲染視圖(使用正確的數據更新 DOM 元素)
this.render();
},
handleClick() {
return controller.incrementCounter();
},
render() {
// 使用當前汽車的數據更新 DOM 元素
const currentCar = controller.getCurrentCar();
this.countElem.textContent = currentCar.clickCount;
this.carNameElem.textContent = currentCar.name;
this.carImageElem.src = currentCar.imgSrc;
this.carImageElem.style.cursor = 'pointer';
},
};
控制器(大腦)
控制器負責獲取數據、修改數據,併爲用戶提供數據。本質上,控制器就是視圖和模型之間的鏈接。
通過 getter 和 setter 函數,控制器從模型拉取數據並初始化視圖。
如果視圖要更新後臺數據,它會通過 setter 函數來修改數據。
const controller = {
init() {
// 將當前展示的車設爲列表中的第一輛車
model.currentCar = model.cars[0];
// 初始化視圖
carListView.init();
carView.init();
},
getCurrentCar() {
return model.currentCar;
},
getCars() {
return model.cars;
},
// 把“當前選中汽車”設爲傳入的對象
setCurrentCar(car) {
model.currentCar = car;
},
// 增加當前選中汽車的計數
incrementCounter() {
model.currentCar.clickCount++;
carView.render();
},
};
// Let's goooo!
controller.init();
MVC 框架
JavaScript 越來越受歡迎,近年來還接管了後端。越來越多成熟的 JavaScript 應用選擇了 MVC 架構模式。
框架來來去去,但是 MVC 架構模式的概念是不變的。
運用了這些概念的早期框架包括:KnockoutJS、Django、Ruby on Rails。
總結
MVC 模式最吸引人的概念是關注點分離。
現代 web 應用非常複雜,有時做一些修改會令人很頭疼。
將前端和後端作爲獨立的小組件來管理,可以使應用更靈活、更易於維護和擴展。
**如果你想了解這個 Car Clicker 應用,可以查看__源碼__或體驗__在線版本_。_**
🌟感謝你的閱讀!🌟
原文鏈接:https://www.freecodecamp.org/news/the-model-view-controller-pattern-mvc-architecture-and-frameworks-explained/
作者:Rafael D. Hernandez
譯者:Humilitas
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/bfyJhP_zJ5CRI9XTCkFJgQ