什么是MVC
每个模块都可以写成三个对象,分别是M、V、C
M-Model(数据模型)负责操作所有数据
模型model用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法,会有一个或多个视图监听此模型。一旦模型的数据发生变化,模型将通知有关的视图。
V-View(视图)负责所有UI界面
视图view是它在屏幕上的表示,描绘的是model的当前状态。当模型的数据发生变化,视图相应地得到刷新自己的机会。
C-CONtroller(控制器)负责其他
控制器controller定义用户界面对用户输入的响应方式,起到不同层面间的组织作用,用于控制应用程序的流程,它处理用户的行为和数据model上的改变。
其中涉及两种设计模式:
- view和model之间的观察者模式,view观察model,事先在此model上注册,以便view可以了解在数据model上发生的改变。
- view和controller之间的策略模式
各个部分的伪代码实现
Model
const m = {
data: { //需要操作的数据或信息 },
create: { //增数据 },
delete: { //删数据 },
update(data) { //改数据
Object.assign(m.data, data) //使用新数据替换旧数据
eventBus.trigger('m:upate') // eventBus触发'm:update'信息, 通知View刷新
},
get:{ //获取数据 }
}
View
const v = {
el: null,
html: `<div>...</div>`, //html上的内容
init(container) {
v.el = $(container) //需要刷新的元素
},
render(){ //刷新页面
}
}
Controller
const c = {
init(){
v.init() // View初始化
v.render() // 第一次渲染
c.autoBindEvents() // 自动的事件绑定
eventBus.on('m:update', () => { v.render() })
// 当eventBus触发'm:update'时View刷新
},
events:{
'click #add1':'add'
//事件以哈希表方式记录 },
method() {
data = 改变后的新数据
m.update(data)
},
autoBindEvents() { //自动绑定事件 }
}EventBus
EventBus
EventBus一般用到以下三个API:
- on(eventName, fn):用于监听事件,eventName传事件名字, fn传执行函数
- trigger(eventName, data):用于触发事件,eventName传事件名字,data传其他参数
- off(eventName, fn):用于取消监听,eventName传事件名字,fn传解绑的函数
伪代码例子:
const fn=() => {}
eventBus.trigger("m:updated");//触发m:updated事件
eventBus.on("m:updated", fn);//监听m:updated事件,如果m:updated事件被触发,执行函数fn
eventBus.off("m:updated", fn);//事件m:updated解绑函数fn,如果m:updated事件被触发,不再执行函数fn
什么是表驱动编程
表驱动法是一种编程模式,从表(哈希表)里面查找信息而不是使用逻辑语句(if…else…switch等),可以减少重复代码,只将重要的信息放在表里,然后利用表来编程,与逻辑语句相比较有着更稳定的复杂度。
如:下面这段代码重复率很高
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)
})
}
当我们使用表驱动法后,可写为
events: {
'click #add1' : 'add',
'click #minus1' : 'minus'
},
add() {
m.update( data: {n: m.data.n +1})
},
minus() {
m.update( data: {n: m.data.n -1})
}
我是如何理解模块化的
- 我的理解是将一个较复杂的项目文件,将这个文件中的各个部分或功能分割成各个模块(文件)去开发实现,这使得模块可以独立开发,在工作中,不同的模块也就可以交由不同的开发人员。
- 而且在开发中我们也会用到一些共同API,这个时候我们也可以把这些抽离成一个公用模块,当需要引用这个函数或者功能的时候,只需要在相应的模块里面用import导入相应的包。
- 使用模块化编程可以便于我们对该项目的后续维护和修改,不需要从大量的代码中寻找所需维护和修改的部分,能精准地找到我们所需维护或修改的模块,以及各个模块互不干扰,分开实现,不会因为某一个部分的出错,而影响到其他部分。而且模块化可以降低代码耦合度,减少重复代码,提高代码利用率。