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(主持人),同时改变了通信方向。
- 各部分之间的通信,都是双向的。
- View 与 Model 不发生联系,都通过 Presenter 传递。
- View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
MVVM
MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。
唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。Vue 采用这种模式。
实例
功能:select 选择器选择哪个展示哪个
<select id&#61;"drinkSelect"><option value&#61;"coffee">coffee</option><option value&#61;"milk">milk</option><option value&#61;"juice">juice</option>
</select>
<p id&#61;"theColorOfDrink"></p><script type&#61;"text/Javascript">
document.getElementById("drinkSelect").onchange &#61; function() {var color;var colorOfDrink &#61; {"coffee":"brown","milk":"white","juice":"orange"};color &#61; colorOfDrink[this.value];document.getElementById("theColorOfDrink").innerHTML &#61; color;
}
</script>
改为 MVC
<select id&#61;"drinkSelect"><option value&#61;"coffee">coffee</option><option value&#61;"milk">milk</option><option value&#61;"juice">juice</option>
</select>
<p id&#61;"theColorOfDrink"></p><script type&#61;"text/Javascript">
var showDrinkColor &#61; {start:function(){this.view.start();},set:function(drinkName){this.model.setDrink(drinkName);}
};
showDrinkColor.model &#61; {colorOfDrink:{"coffee":"brown","milk":"white","juice":"orange"},selectedDrink:null,setDrink:function(drinkName){this.selectedDrink &#61; this.colorOfDrink[this.selectedDrink]?drinkName:null;this.onchange();},onchange:function(){showDrinkColor.view.update();},getDrinkColor:function(){return this.selectedDrink?this.colorOfDrink[this.selectedDrink]:"white";}
};
showDrinkColor.view &#61; {start:function(){document.getElementById("drinkSelect").onchange &#61; this.onchange;},onchange:function(){showDrinkColor.set(document.getElementById("drinkSelect").value);},update:function(){document.getElementById("theColorOfDrink").innerHTML &#61; showDrinkColor.model.getDrinkColor();}
};
showDrinkColor.start();
</script>
总结
以下是我个人的一些理解&#xff1a;
如果把整个 web 开发看做一个整体&#xff0c;那么前后端不分离时期的 MVC&#xff1a;
- M&#61;后端操作数据等
- V&#61;后端模板渲染的视图
- C&#61;后端路由等
如果把整个 web 开发看做一个整体&#xff0c;那么前后端分离时期的 MVC&#xff1a;
- M&#61;后端CRUD
- V&#61;前端视图层
- C&#61;前端控制器
对于纯web后台的&#xff0c;MVC是&#xff1a;
- M&#61;数据对象 &#43; 数据访问 &#43; 业务逻辑&#xff0c;必要时可以分层
- C&#61;路由 &#43; 视图逻辑
- V&#61;接口开发这层可以不要
对于纯前端的&#xff0c;MVC是&#xff1a;
- M&#61;前端数据层&#xff0c;比如 vue 中的 data
- C&#61;路由 &#43; 视图逻辑
- V&#61;前端视图
以下是别人的一些理解
- MVC也好&#xff0c;MVP也好&#xff0c;MVVM也好&#xff0c;重要的是针对应用场景和需求对M、V、C三层进行划分&#xff0c;三层间的交互也是如此。只要确定了架构后遵循一定的原则&#xff0c;在开发过程中尽量不破坏原有规则&#xff0c;直到现有的架构规则不能满足需求&#xff0c;再重新制定。这样应该就能在满足应用场景需求的同时&#xff0c;使得项目有明确清晰的层次。在比较框架的定义和优劣时&#xff0c;也要有一定的场景说明才有实际意义。
- MVC在bs架构和cs架构上差别很大&#xff0c;即使同是bs&#xff0c;因为使用的技术的差别&#xff0c;业务的差别&#xff0c;架构的差别&#xff0c;MVC的通信方式也会和原来你书本上看到的不一样。就像backbonejs和angularjs的出现&#xff0c;是发明还是延伸&#xff0c;还是糟蹋&#xff1f;每天和它一起工作的人才知道。
所有的设计应该以贴近自然或接近自然规律为目标。再通俗的讲&#xff0c;用的舒服就是自然。好的东西绝对不需要强记一堆原理来理解的。