JavaScript设计模式|8月更文挑战

156 阅读3分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

为了方便回忆快速使用设计模式

设计模式介绍

设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

1.单例模式

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 总结: 保证一个类只有唯一的实例对象, 全局登陆框

const createLoginLayer = function() {
  const div = document.createElement('div')
  div.innerHTML = '唯一登陆框'
  div.style.display = 'none'
  document.body.appendChild(div)
  return div
}

const getSingle = function(fn) {
  let result
  return function() {
    return result || (result = fn.apply(this, arguments))
  }
}
const createSingleLoginLayer = getSingle(createLoginLayer)

document.getElementById('loginBtn').onclick = function() {
  createSingleLoginLayer()
}

2.策略模式

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。 总结: 根据不同状态参数执行不同的方法, 红绿灯,播放器的状态

const strategy = {
  'S': function(salary) {
    return salary * 4
  },
  'A': function(salary) {
    return salary * 3
  },
  'B': function(salary) {
    return salary * 2
  }
}

const calculateBonus = function(level, salary) {
  return strategy[level](salary)
}

calculateBonus('A', 10000) // 30000

3.代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。 总结: 为其他对象提供一种代理以控制对这个对象的访问, 起到中间层作用,不让过多接触该对向的所有属性或方法,eg:图片预览

const myImage = (function() {
  const imgNode = document.createElement('img')
  document.body.appendChild(imgNode)
  return {
    setSrc: function(src) {
      imgNode.src = src
    }
  }
})()

const proxyImage = (function() {
  const img = new Image()
  img.onload = function() { // http 图片加载完毕后才会执行
    myImage.setSrc(this.src)
  }
  return {
    setSrc: function(src) {
      myImage.setSrc('loading.jpg') // 本地 loading 图片
      img.src = src
    }
  }
})()
proxyImage.setSrc('http://loaded.jpg')

4.迭代器模式

这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。 总结: 获取对象的顺序和元素方法,eg: es6的迭代器

5.命令模式

将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化,像图片编辑这种多个命令操作记录、撤销、重做

const setCommand = function(button, command) {
  button.onClick = function() {
    command.excute()
  }
}

// --------------------  上面的界面逻辑由A完成, 下面的由B完成

const menu = {
  updateMenu: function() {
    console.log('更新菜单')
  },
}

const UpdateCommand = function(receive) {
  return {
    excute: receive.updateMenu,
  }
}

const updateCommand = UpdateCommand(menu) // 创建命令

const button1 = document.getElementById('button1')
setCommand(button1, updateCommand)

6.组合模式

依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。 这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

7.责任链模式

通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。 不断执行,直到所有流程通过后

// 类似这样的链路代码
const order500 = function(orderType, pay, stock) {}
const order200 = function(orderType, pay, stock) {}
const orderCommon = function(orderType, pay, stock) {}

Function.prototype.after = function(fn) {
  const self = this
  return function() {
    const result = self.apply(self, arguments)
    if (result === 'nextSuccess') {
      return fn.apply(self, arguments) // 这里 return 别忘记了~
    }
  }
}

const order = order500.after(order200).after(orderCommon)

order( 3, true, 500 ) // 普通购买, 无优惠券

还有更多的设计模式