浅析MVC

你可以看到的:


MVC
EventBus
表驱动编程
我对模块化的理解


源码:https://github.com/woshidw/mvc-demo-1

--资料来源于饥人谷

什么是MVC


MVC是出名的设计模式,所有的页面都可以使用 MVC来优化代码结构。页面可以分为很多模块,每个模块都可以写成三个对象,分别是M、V、c

MVC三类对象

MVC模式(Model-view-controller) 是一种设计模式(软件架构)。
MVC包括三类对象,将它们分离以提高灵活性和复用性。

  • 模型(Model) : 同于数据管理, 一旦模型的数据发生改变,Model将通知有关的视图。
  • 视图(View) : 负责用户界面,HTML渲染。 描绘的是Model的当前状态,当模型的数据发生改变,View就会刷新自己。
  • 控制(Controller) : 控制器, Controll 控制其他所有流程。 负责监听并处理视图(View)的事件。更新和调用Model。也负责监听Model的变化,并更新View。
const m = {
  data: {
    index: parseInt(localStorage.getItem(localKey)) || 0
  },
  create() {},
  delete() {},
  update(data) {
    Object.assign(m.data, data)
    eventBus.trigger('m:updated')
    localStorage.setItem('index', m.data.index)
  },
  get() {}
}

由于M是负责操作数据的,我们将我们所需要的变量index存入到了m对象中,这就是Model

const v = {
  el: null,
  html: (index) => {
    return `
    <div>
      <ol class="tab-bar">
        <li class="${index === 0 ? 'selected' : ''}" data-index="0"><span>1111</span></li>
        <li class="${index === 1 ? 'selected' : ''}" data-index="1"><span>2222</span></li>
      </ol>
      <ol class="tab-content">
        <li class="${index === 0 ? 'active' : ''}">内容1</li>
        <li class="${index === 1 ? 'active' : ''}">内容2</li>
      </ol>
    </div>
`
  },
  init(container) {
    v.el = $(container)
  },
  render(index) {
    if (v.el.children.length !== 0) v.el.empty()
    $(v.html(index)).appendTo(v.el)
  }
}

由于V是负责操作视图的,我们将所需要的添加的html文件以及渲染的函数封装到了V对象中

const c = {
  init(container) {
    v.init(container)
    v.render(m.data.index) // view = render(data)
    c.autoBindEvents()
    eventBus.on('m:updated', () => {
      v.render(m.data.index)
    })
  },
  events: {
    'click .tab-bar li': 'x',
  },
  x(e) {
    const index = parseInt(e.currentTarget.dataset.index)
    m.update({index: index})
  },
  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)
    }
  }
}

C代表的是其他的一些操作,这里放入了绑定事件,以及初始化事件。

我们要用最小知识原则

最小知识原则


引入一个模块需要引入 html、css、js


引入一个模块需要引入 html、js


引入一个模块需要引入 js


你需要知道的知识越少越好


模块化为这一点奠定了基础


用模块化用户只会看到一个js的文件,其他的文件都被我们通过export import 导入导出的方式放到了我们的js代码中,即可实现网页的展示
大家可以清晰的看到,我们将每一个部分都各自的抽成了一个模块,当我们需要改动数据,或者需要修改绑定事件时只需要去对应的位置进行修改即可,这就是MVC设计模式


EventBus

  • 比如用vue, new一个新的vue,它是一个实例对象。
  • 但是最重要的在于它原型上有我们用到的on(监听)、on(监听)、on(监听)、off(解绑)、$emit(触发)等API 。

EventBus作用:

  • EventBus 主要用于对象间的通信,
  • 使用 EventBus 可以满足最小知识原则,model和view互相不知道对方的细节,但是却可用调用对方的功能。
const eventBus = $(window)
eventBus.trigger('m:update') // 自动触发事件update
eventBus.on('m:update', () => {console.log('触发';)}) //监听事件 然后执行函数

表驱动编程


当我们需要判断 3 种以上的情况,做出相应的事情,往往需要写很多很多的 if else,这样的代码可读性不强。


为了增强代码的可读性,我们可以用表驱动编程,把用来做 if 条件判断的值存进一个哈希表,然后从表里取值。


而这种做法的意义就在于: 逻辑和数据是分离的
举个例子,比如国家简写转换,给一个国家全名,转换成国家简写,用if else语法来写:

//  伪代码
function contry(国家名){
	if(中国){
    	return "CHN"
    }else if(日本){
    	return "JPN"
    }else if(美国){
    	return "USA"
    }else{
    	return "OTHER"
    }
}

用 if else语句这样做,如果我再增加一个国家,那么就要写一个if else语句。等于又增加了一条逻辑。


那么我们为何不用 表数据编程 把 数据和逻辑分离开实现呢。


毕竟,数据的添加是简单,低成本和低风险的。 而逻辑的添加是负责,高成本和高风险的。


表驱动编程做法:

伪代码
function contry(国家名){
	const 国家列表 = [
    	"中国"  = "CHN"
    	"日本"  = "JPN"
    	"美国"  = "USA"
    ]
   国家简写转换:funciton(){
   	for(let 国家名 in 国家列表){
    	return 国家列表[国家名]  // 返回的就是 国家简写
    }
   }
}

这样做的话,如果再添加一个国家名(数据),那么我们只需国家列表(数组)中添加一项即可。逻辑方面的我们一点都不需要更改,更别说去考虑逻辑了。


这样,我们就脱离了数据与逻辑的关系了。
**
参考文章: 用表驱动编程重构if-else的意义


如何理解模块化


将一个复杂的程序依据一定的规则(规范)封装成几个块(文件)并进行组合。


模块的内部数据的实现是私有的,只是向外部暴露一些接口(方法)与外部其他模块通信。这则就是模块化。


好处:

  • 降低代码耦合度
  • 减少重复代码
  • 提高代码重用性
  • 在项目结构上更加清晰,便于维护。


若在模块中我们都采用的是jquery的库,若以后公司不使用该库,我们可以直接修改对应的模块即可,倘若全都在一个js文件中,极其的不利于我们的修改,同时还增加了我们对代码的复用性,若有哪个地方需要用到一个独立的类,或者方法直接import导入即可使用

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值