MVC、MVP、MVVM的区别

MVC

视图(View):用户界面。
控制器(Controller):业务逻辑
模型(Model):数据操作
V -> C -> M -> C -> V。

Model:即数据模型,用来包装和应用程序的业务逻辑相关的数据或者对数据进行处理,模型可以直接访问数据。表示着业务逻辑和数据,模型把这些数据逻辑渲染到 View 中,比较常见的做法是后端的模版技术,例如 jsp 之类的,把预期的数据填入 jsp 模版中,返回给浏览器。当然,像现在的 restful 应用中,前端都为 SPA 单页面应用,那么 api 返回的 json 数据也相当于为 View。

View:视图用来有目的显示数据,在视图中一般没有程序上的逻辑,为了实现视图上的最新功能,视图需要访问它监视的数据模型。负责 UI 渲染工作,传统的 MVC 中,一个 View 就是一个 Web 页面,通常还有有 Javascript 代码在其中负责一些页面逻辑。

Controller:控制器调控模型和视图的联系,它控制应用程序的流程,处理事件并作出响应,事件不仅仅包括用户的行为还有数据 模型上的改变。通过捕获用户事件,通知模型层作出相应的更新处理,同时将模型层的更新和改变通知给视图,使得视图作出相应改变。因此控制器保证了视图和模型的一致性。

Controller 控制器就相当于一个分发的工具,熟悉 Spring 的同学肯定就知道这就是 Spring 中的 @Controller,一个请求进来,需要什么样的 Model,获取什么样的数据,返回什么样的页面,都是 Controller 的工作。

一般来说,MVC 中的数据流动是单向的,Model 用数据来渲染 View,View 用户界面交互完成后更新数据,然后 Controller 做分发和控制。但是从交互的角度来看并不是单向的,有些情况下,Controller 当收到更新数据请求的时候,Controller 会更新数据,更新完就会重定向到的 View ,View 拿到更新完的 Model 数据,进行渲染,Controller 多充当了一个调度者的角色。

MVP

MVP 模式将 Controller 改名为 Presenter(主持人),同时改变了通信方向。
MVC、MVP、MVVM的区别_第1张图片

  1. 各部分之间的通信,都是双向的。
  2. View 与 Model 不发生联系,都通过 Presenter 传递。
  3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。

MVVM

MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。

MVC、MVP、MVVM的区别_第2张图片
唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。Vue 采用这种模式。

实例

功能:select 选择器选择哪个展示哪个

<select id="drinkSelect">
    <option value="coffee">coffee</option>
    <option value="milk">milk</option>
    <option value="juice">juice</option>
</select>
<p id="theColorOfDrink"></p>

<script type="text/javascript">
document.getElementById("drinkSelect").onchange = function() {
    var color;
    var colorOfDrink = {
        "coffee":"brown",
        "milk":"white",
        "juice":"orange"
    };
    color = colorOfDrink[this.value];
    document.getElementById("theColorOfDrink").innerHTML = color;
}
</script>

改为 MVC

<select id="drinkSelect">
    <option value="coffee">coffee</option>
    <option value="milk">milk</option>
    <option value="juice">juice</option>
</select>
<p id="theColorOfDrink"></p>

<script type="text/javascript">
//showDrinkColor is Controller
var showDrinkColor = {
    start:function(){
        this.view.start();
    },
    set:function(drinkName){
        this.model.setDrink(drinkName);
    }
};
//Model
showDrinkColor.model = {
    colorOfDrink:{
        "coffee":"brown",
        "milk":"white",
        "juice":"orange"
    },
    selectedDrink:null,
    setDrink:function(drinkName){
        this.selectedDrink = this.colorOfDrink[this.selectedDrink]?drinkName:null;
        this.onchange();
    },
    onchange:function(){
        showDrinkColor.view.update();
    },
    getDrinkColor:function(){
        return this.selectedDrink?this.colorOfDrink[this.selectedDrink]:"white";
    }
};
//View
showDrinkColor.view = {
    start:function(){
        document.getElementById("drinkSelect").onchange = this.onchange;
    },
    onchange:function(){
        showDrinkColor.set(document.getElementById("drinkSelect").value);
    },
    update:function(){
        document.getElementById("theColorOfDrink").innerHTML = showDrinkColor.model.getDrinkColor();
    }
};
showDrinkColor.start();
</script>

总结

以下是我个人的一些理解:

如果把整个 web 开发看做一个整体,那么前后端不分离时期的 MVC:

  • M=后端操作数据等
  • V=后端模板渲染的视图
  • C=后端路由等

如果把整个 web 开发看做一个整体,那么前后端分离时期的 MVC:

  • M=后端CRUD
  • V=前端视图层
  • C=前端控制器

对于纯web后台的,MVC是:

  • M=数据对象 + 数据访问 + 业务逻辑,必要时可以分层
  • C=路由 + 视图逻辑
  • V=接口开发这层可以不要

对于纯前端的,MVC是:

  • M=前端数据层,比如 vue 中的 data
  • C=路由 + 视图逻辑
  • V=前端视图

以下是别人的一些理解

  • MVC也好,MVP也好,MVVM也好,重要的是针对应用场景和需求对M、V、C三层进行划分,三层间的交互也是如此。只要确定了架构后遵循一定的原则,在开发过程中尽量不破坏原有规则,直到现有的架构规则不能满足需求,再重新制定。这样应该就能在满足应用场景需求的同时,使得项目有明确清晰的层次。在比较框架的定义和优劣时,也要有一定的场景说明才有实际意义。
  • MVC在bs架构和cs架构上差别很大,即使同是bs,因为使用的技术的差别,业务的差别,架构的差别,MVC的通信方式也会和原来你书本上看到的不一样。就像backbonejs和angularjs的出现,是发明还是延伸,还是糟蹋?每天和它一起工作的人才知道。
    所有的设计应该以贴近自然或接近自然规律为目标。再通俗的讲,用的舒服就是自然。好的东西绝对不需要强记一堆原理来理解的。

你可能感兴趣的:(架构,架构)