常听说 spring MVC,现在都发展到前端 MVC 了
定义
经典 MVC 模式中,M 是指 Model 业务模型,V 是指 View 用户界面,C 则是 Controller 控制器
通常是为了使得代码模式固化,让代码复杂度相对稳定
表现
后端
比如在 spring 中,Model 通常包括 domain、mapper、dao 等三层,定义了对象模型以及对象对应的存取方法
1 | // domain |
Controller 则是 controller 层 和 service 层,定义了数据接口和关于数据处理的业务方法
1 | // service |
特别的,当 controller 的注解是 @RestController 的时候,仅作为数据接口
当注解是 @Controller 的时候,可以返回数据或页面,比如 thymeleaf 渲染的页面
这时候,返回页面的 controller 就是所谓的 View
1 | "") ( |
前端
而在前端中,一般不需要考虑与数据库的交互,数据来源一般都是后端提供的数据接口
这时候,Controller 就不需要提供数据接口,只需要访问,于是原本在后端分离开的 controller 和 service 就融合在了一起,负责提供业务方法
1 | const Controller = el => { |
Model 则是负责保存需要用到的用户数据,并为数据设置事件
1 | const Model = { |
View 则是负责接收业务方法的信号,重新渲染页面,监听数据事件
1 | const View = { |
于是又多了一个和后端不一样的地方——model 和 view 都要关注用户事件
所以前端 MVC 一般还有一个概念,就是 EventBus 事件总线
EventBus 提供一系列事件绑定、触发、解除等相关的方法,然后交由 Model 和 View 来调用
1 | const EventBus = { |
但是现在这些方法怎么转移使用呢?
基于 js 的特性,可以选择原型链继承或者类继承
此处可以选择类继承,让 Model、View、EventBus 都成为 class
然后 Model、View 都 extends EventBus,就可以拥有 EventBus 的所有方法
之后在使用的时候,声明一个该类的实例即可
表驱动编程
上述伪代码中,我们采用了遍历 model.events 的方法来为 events 里的每个键值对都执行绑定
实际上就是先为要绑定的列表作成一个哈希表,然后遍历这个表
基于这种方法的编程,代码复杂度恒定——无论增加多少个表项,都不需要修改绑定部分的业务代码
模块化
其实 MVC 也就是一种模块化,毕竟代码分离了
模块化说到底就是为了方便维护各个部分的代码
比如同一个页面上有多块不同的功能,这时候我总不可以牵一发而动全身吧,那重构和渲染成本也太高了
这时候就可以选择在编程的时候模块化,使得代码耦合度降低,上层实现不直接依赖于底层架构
具体来说就是我们可以把页面上的每个不同功能的部分都应用一次 MVC 架构,这样每个部分都是直接依赖 MVC 提供的接口,而不关心内部的实现
就像前后端通信一样,只需要接口文档规定好,不需要调用者去关心接口内部是怎么写的
既然前后端分离的好处显而易见,那模块分离的好处,是不是也同理呢?
感谢阅读