浅析 MVC
【目录】
一、MVC 三个对象分别做什么
二、EventBus 有哪些 API,是做什么用的
三、表驱动编程是做什么的
【前言】
MVC 是一种软件架构模式或者叫 MVC 框架;由模型(Model)、视图(View)、控制器(Controller)构成。该模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用可能。除此之外,此模式透过对复杂度的简化,使程序结构更加直观。透过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。
【正文】
一、MVC 三个对象分别做什么
每个模块都可以写成三个对象,分别是M、V、C
- M(Model:数据模型): 负责操作所有的数据
- V(View:视图): 负责所有的UI界面
- C(Controller:控制器): 负责其他
现在给出一个需求:给一个初始数字,然后用户可以进行+、-、*、/的相关操作,来看下MVC三个对象在代码中的具体实现,
1、M对象操作所有的数据
数据相关都放到m,(采用伪代码,理解思路即可)
const m = {
data: {数据A},
create() {},
delete() {},
update(data) {
Object.assign(m.data,data)//用新数据替换旧数据
eventBus.trigger('m:update')//eventBus触发'm:update'信息,通知View刷新界面
},
get() {数据A}
}
2、V对象负责所有的UI界面
视图相关都放到v,代码如下:
const v = {
el: 需要刷新的元素,
html: `
body里面的内容
`,
init(container) {
v.el = $(container)
},
render(n) {刷新页面}
}
3、C对象负责其他
其他都放到c对象中,代码如下:
const c = {
init(container) {
v.init()//初始化View
v.render()//第一次渲染页面
c.autoBindEvents()//自动的事件绑定
eventBus.on('m:update',()=>{v.render()}//当enentsBus触发'm:update'是View刷新
},
events: {事件 }, //事件以哈希表的方式记录存储
add() {+具体实现},
minus() {-具体实现},
mul() {*具体实现},
div() {/具体实现},
autoBindEvents() {自动绑定事件}
}
二、EventBus 有哪些 API,是做什么用的
1、什么是EventBus?
简单的说,就是一个以事件为驱动的消息服务总线
2、Web平台运行期为什么要用EventBus?
- 便于业务逻辑解耦
- 提供丰富的扩展点,包括前扩展、后扩展和覆盖
- 使用事件驱动,让事件触发更加清晰
- 让代码更加简洁清楚
3、Web平台运行期在那些地方使用了EventBus?
- 业务逻辑调度中心,包括前端、Web服务端任何地方
- 通过EventBus集成各种超类、模板、页面
- 通过EventBus集成各种系统服务与业务组件
4、EventBus 有哪些 API?
- on : 监听事件
- trigger(emit) : 触发事件
- off : 取消监听
//EventBus.js
class EventBus {
constructor() {
this._eventBus = $(window)
}
on(eventName, fn) {
return this._eventBus.on(eventName, fn)
}
trigger(eventName, data) {
return this._trigger.trigger(eventName, data)
}
off(eventName, fn) {
return this._eventBus.off(eventName, fn)
}
}
export default EventBus
//new.js
import EventBus from 'EventBus.js'
const e = new EventBus()
e.on()
e.trigger()
e.off()
EventBus3.0源码地址:https://github.com/greenrobot/EventBus
三、表驱动编程是做什么的
表驱动编程方法是一种使你可以在表中查找信息,而不必用很多的逻辑语句(if或Case)来把它们找出来的方法。在简单的情况下,逻辑语句往往更简单而且更直接。但随着逻辑链的复杂,复杂度也会越来越高。表就可以减少重复代码,只将重要的信息放在表里,然后利用表来编程,与逻辑语句相比较有着更稳定的复杂度。
以下两段代码进行对比即可发现用表驱动编程方法可以使代码变得更为简洁。
1、没有使用表驱动编程的代码
bindEvents(){
v.el.on('click', '#add1', () => {
m.data.n += 1
v.render(m.data.n)
})
v.el.on('click', '#minus1', () => {
m.data.n -= 1
v.render(m.data.n)
})
v.el.on('click', '#mul2', () => {
m.data.n *= 2
v.render(m.data.n)
})
v.el.on('click', '#divide2', () => {
m.data.n /= 2
v.render(m.data.n)
})
}
2、运用了表驱动编程的代码(将事件提取出一个哈希表,使逻辑和数据分离开)
events: {
'click #add1' : 'add',
'click #minus1' : 'minus',
'click #mul2' : 'mul',
'click #divide2' : 'div'
},
add() {
m.update( data: {n: m.data.n +1})
},
minus() {
m.update( data: {n: m.data.n -1})
},
mul() {
m.update( data: {n: m.data.n *2})
},
div() {
m.update( data: {n: m.data.n /2})
}
会发现通过表驱动编程之后代码逻辑变的更为清晰简洁了。
【扩展】
一、我是如何理解模块化的?
1、代码模块化之后无论是代码的整体性还是后期进行代码维护都变的清晰简单了起来。例如与逻辑相关的代码统一放到JS文件中,与视图相关的统一放到html文件中,与样式相关的统一放到css文件中。
2、业务模块化之后可以使业务流程更为清晰,便于开展工作,各个业务模块之间负责自己模块的业务,也避免了一些不必要的麻烦,使得工作的效率也会更高。
3、模块化我觉得是一种高效的思想,这在编程过程中提供了一种优化代码以及重构代码的方向。
二、与模块相关的两个命令
一般来说,一个模块就是一个独立的文件,该文件内部的所有变量,外部无法获取,如果你希望外部能够读取模块内部的某个变量,就必须使用export命令输出该变量,使用import命令输入其他模块提供的功能。