模型视图控制器模式 - MVC 架构和框架解释

MVC 架构模式将复杂的应用程序开发转变为更易于管理的过程。它允许多个开发人员同时在应用程序上工作。

当我第一次了解 MVC 模式时,我被所有的行话吓到了。当我开始将这些概念应用于实际应用程序时,更是如此。

通过退后一步关注 MVC 是什么以及它可以完成什么,可以更容易地理解该模式并将其应用于任何 Web 应用程序。

什么是 MVC?

MVC 代表模型-视图-控制器。以下是每个组件的含义:

  • 模型:包含所有数据逻辑的后端
  • 视图:前端或图形用户界面 (GUI)
  • 控制器:控制数据显示方式的应用程序的大脑

MVC 的概念首先由 Trygve Reenskaug 引入,他提出将其作为开发桌面应用程序 GUI 的一种方式。

今天,MVC 模式用于现代 Web 应用程序,因为它允许应用程序可扩展、可维护且易于扩展。

为什么要使用 MVC?

三个词:关注点分离,简称SoC。

MVC 模式可帮助您将前端和后端代码分解为单独的组件。这样,管理和更改任何一方都更容易,而不会相互干扰。

但这说起来容易做起来难,尤其是当几个开发人员需要同时更新、修改或调试一个成熟的应用程序时。

如何使用 MVC

为了更好地说明 MVC 模式,我包含了一个 Web 应用程序,它展示了这些概念是如何工作的。

My Car Clicker 应用程序是著名的 Cat Clicker 应用程序的变体。

以下是我的应用程序中的一些主要区别:

  1. 没有猫,只有肌肉车图像(对不起猫爱好者!)
  2. 列出了多种车型
  3. 有多个点击计数器
  4. 它只显示选定的汽车

现在让我们深入了解构成 MVC 架构模式的这三个组件。

模型(数据)

模型的工作是简单地管理数据。无论数据来自数据库、API 还是 JSON 对象,模型都负责管理它。

在 Car Clicker 应用程序中,模型对象包含一个汽车对象数组,其中包含应用程序所需的所有信息(数据)。

它还使用最初设置为 的变量管理正在显示的当前汽车null

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',
        },
    ],
};

视图(用户界面)

视图的工作是决定用户将在他们的屏幕上看到什么,以及如何看到。

Car Clicker 应用程序有两个视图:carListViewCarView.

两个视图都有两个关键函数,它们定义了每个视图想要初始化和渲染的内容。

这些功能是应用程序决定用户将看到什么以及如何看到的地方。

汽车列表视图

const carListView = {
    init() {
        // store the DOM element for easy access later
        this.carListElem = document.getElementById('car-list');

        // render this view (update the DOM elements with the right values)
        this.render();
    },

    render() {
        let car;
        let elem;
        let i;
        // get the cars to be render from the controller
        const cars = controller.getCars();

        // to make sure the list is empty before rendering
        this.carListElem.innerHTML = '';

        // loop over the cars array
        for(let i = 0; i < cars.length; i++) {
            // this is the car we've currently looping over
            car = cars[i];

            // make a new car list item and set its text
            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)
            );
            // finally, add the element to the list
            this.carListElem.appendChild(elem);
        }
    },
};

车景

const carView = {
    init() {
        // store pointers to the DOM elements for easy access later
        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');


        // on click, increment the current car's counter
        this.carImageElem.addEventListener('click', this.handleClick);

        // render this view (update the DOM elements with the right values)
        this.render();
    },

    handleClick() {
    	return controller.incrementCounter();
    },

    render() {
        // update the DOM elements with values from the current car
        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() {
        // set the current car to the first one in the list
        model.currentCar = model.cars[0];

        // tell the views to initialize
        carListView.init();
        carView.init();
    },

    getCurrentCar() {
    	return model.currentCar;
    },

    getCars() {
    	return model.cars;
    },

    // set the currently selected car to the object that's passed in
    setCurrentCar(car) {
    	model.currentCar = car;
    },

    // increment the counter for the currently-selected car
    incrementCounter() {
        model.currentCar.clickCount++;
        carView.render();
    },
};

// Let's goooo!
controller.init();

MVC 框架

JavaScript 越来越受欢迎,并且近年来它已经接管了后端。越来越多成熟的 JavaScript 应用程序以一种或另一种方式选择了 MVC 架构模式。

框架来来去去,但一直不变的是从 MVC 架构模式中借来的概念。

一些应用这些概念的早期框架是KnockoutJSDjangoRuby on Rails。

结论

MVC 模式最吸引人的概念是关注点分离。

现代 Web 应用程序非常复杂,进行更改有时会让人头疼。

在更小的、独立的组件中管理前端和后端允许应用程序具有可扩展性、可维护性和易于扩展性。

**如果您想查看 Car Clicker 应用程序,代码可在GitHub 上获得或在此处查看实时版本。**

🌟感谢您阅读本文!🌟

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值