花了几天的时间熟悉了MVC的思想,回头发现自己以前写的代码弱(太)爆(多)了,记一篇博客回顾所学。
以下内容代表自己的思考,结论并非一定正确。
什么是MVC
一句话概括:MVC是一种架构设计模式,它通过关注点分离鼓励改进应用程序组织。
- M:Model(数据类型)负责操作所有数据
- V:View(视图)负责所有UI界面
- C:Controller(控制器)负责其他
MVC的M,V,C分别做什么
一图流:
给出以下示例
- M:构建一个M,M保存了数据,当M改变的时候,M会通知V。
例如保存缓存,保存方法
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const m = {
data: {
n: parseInt(localStorage.getItem('n'))
},
create() {}
delete() {},
update(data) {
Object.assign(m.data, data)
eventBus.trigger('m:updated')
localStorage.setItem('n', m.data.n)
},
get() {}
}
|
- V:构建一个V,V包含关于视图的部分,当V变化的时候,视图会重新渲染,呈现给用户不一样的界面
包含HTML,以及渲染的方法等
1
2
3
4
5
6
7
8
9
10
11
12
|
const v = {
el: null,
html: ...,
init(container) {
v.el = $(container)
},
render(n) {
if (v.el.children.length !== 0) v.el.empty()
$(v.html.replace('{{n}}', n))
.appendTo(v.el)
}
}
|
- C:构建一个C,C包含各类绑定事件,用户可以操作C,通过C可以改变M,改变V。
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
const c = {
init(container) {
v.init(container)
v.render(m.data.n) // view = render(data)
c.autoBindEvents()
eventBus.on('m:updated', () => {
console.log('here')
v.render(m.data.n)
})
},
events: {
'click #add1': 'add',
'click #minus1': 'minus',
'click #mul2': 'mul',
'click #divide2': 'div',
},
add() {
m.update({n: m.data.n + 1})
},
minus() {
m.update({n: m.data.n - 1})
},
mul() {
m.update({n: m.data.n * 2})
},
div() {
m.update({n: m.data.n / 2})
},
autoBindEvents() {
for (let key in c.events) {
const value = c[c.events[key]]
const spaceIndex = key.indexOf(' ')
const part1 = key.slice(0, spaceIndex)
const part2 = key.slice(spaceIndex + 1)
v.el.on(part1, part2, value)
}
}
}
|
EventBus是做什么用的
EventBus用来进行对象间通信的,在上述的代码M中和C中存在EventBus,这些代码表示一个过程,举个例子,当我调用了C中的add()
方法,会触发M中的update()
,它会把更新过的n分发给所有包含n的数据,更新它们,并且使用EventBus.trigger()
,C中的init()
通过EventBus.on()
监听了trigger
,当触发时,它就会调用一个渲染的方法render()
更新页面。这样的好处就是自动更新,我每次不必在使用add()
的时候在手动写一次render()
渲染页面.
EventBus的api:
EventBus.trigger()
,用于触发()中的内容。
EventBus.on()
,用于监听()中的内容,当监听到时,会触发一个事件
EventBus.off()
,用于监听()中的内容,当监听到时,会结束一个事件
表驱动编程是什么
- 将所有的数据方法放在表中,直接在表中查找,而不必使用逻辑语句,好处是简单直接。
- 它的本质是,从表里查询信息来代替逻辑语句
以下一段代码,通过if,else来判断月份,给出当月的天数。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
if (month === 1) {
return 31;
} else if (month == 2) {
return 28;
}else if (month == 3) {
return 31;
}
...
else if (month == 12) {
return 31;
} else {
return 0;
}
|
上述代码冗长复杂,我们可以把它改写为
1
2
|
array daysPerMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
days = daysPerMonth[month - 1];
|
这样就简洁明了了。
它的优点:
- 更加易读和直白;
- 用数据代替逻辑,容易维护;
- 可以把表中的数据存放在文件中,运行时读取,减少代码体量。数据变更时只需要修改文件;
- 降低复杂度。
以上只是一个最简单的例子,MVC中我们把一个个数据和方法放在了表中,同样实现了这些优点。
我对模块化的理解
通过对MVC的学习,对模块化有了一定的认识,看着代码从复杂到简易,好像渐渐明白了模块化带来的好处
-
什么是模块化
- 模块化就是将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起
- 块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信
-
模块化的优点
- 避免命名冲突(减少命名空间污染)
- 更好的分离, 按需加载
- 更高复用性
- 高可维护性
马上要学习Vue了,这段时间先回顾回顾,夯实一下自己的基础。