js 设计模式

提示

各设计模式说明未填写

构造函数模式

// 构造器模式
class ConstructorDemo {
  constructor({ name, age }) {
    this.name = name
    this.age = age
  }

  getUserInfo() {
    return `${this.name}的年龄为${this.age}`
  }
}
let demo_data = { name: '张三', age: 18 }
let constructor_demo = new ConstructorDemo(demo_data)
console.log(constructor_demo.getUserInfo())
// 张三的年龄为18

适配器模式

介绍

  • 旧的接口/功能和使用者不兼容
  • 中间加个适配器转换接口/功能
class Chinese {
  constructor(name) {
    this.name = name
  }

  getName() {
    return this.name
  }
}

class EnglishName {
  constructor(name) {
    this.people = new Chinese(name)
  }

  getEngName() {
    let name = this.people.getName()
    return `我的中文名是${name},我的英文名是Randy`
  }
}

let user = new EnglishName('张三')
user.getEngName()
// 我的中文名是张三,我的英文名是Randy

装饰器模式

介绍

  • 为新对象添加新的功能
  • 不改变其原有的结构和功能
class Cricle {
  constructor() {}

  draw() {
    console.log('drawing')
  }
}

class Decorator {
  constructor(circle) {
    this.circle = circle
  }

  draw() {
    this.circle.draw()
    this.setBorder(this.circle)
  }

  setBorder(circle) {
    console.log('drawing border')
  }
}

let circle = new Circle()
circle.draw() // drawing
let drawBorder = new Decorator(circle)
drawBorder.draw()
// drawing
// drawing border

工厂模式

介绍

  • new操作单独封装
  • 遇到new时考虑是否用工厂模式
// 简单工厂模式
class FactoryDemo {
  constructor(options) {
    this.type = options.type
    this.list = options.list
  }

  static getTypeList(type) {
    switch (type) {
      case 'farmer':
        return new FactoryDemo({
          type: '农夫山泉',
          list: ['农夫山泉1', '农夫山泉2', '农夫山泉3']
        })
        break
      case 'jingtian':
        return new FactoryDemo({
          type: '景田',
          list: ['景田1', '景田2', '景田3']
        })
        break
      default:
        throw new Error('报错!')
    }
  }
}

let factory_demo = FactoryDemo.getTypeList('farmer')
let factory_demo2 = FactoryDemo.getTypeList('jingtian')
console.log(factory_demo)
console.log(factory_demo2)
// FactoryDemo{type: '农夫山泉',list: ['农夫山泉1', '农夫山泉2', '农夫山泉3']}
// FactoryDemo{type: '景田',list: ['景田1', '景田2', '景田3']}

抽象工厂模式:

// 抽象工厂
class AbstractWaterFactoryDemo {
  constructor(type) {
    if (new.target === AbstractWaterFactoryDemo)
      throw new Error('抽象类不能实例化')
    this.type = type
  }
}

class FarmerWater extends AbstractWaterFactoryDemo {
  constructor(typeName) {
    super('farmer')
    this.typeName = typeName
    this.list = ['农夫山泉1', '农夫山泉2', '农夫山泉3']
  }
}

class JingTianWater extends AbstractWaterFactoryDemo {
  constructor(typeName) {
    super('jingtian')
    this.typeName = typeName
    this.list = ['景田矿泉水1', '景田矿泉水2', '景田矿泉水3']
  }
}

function getFactoryList(type) {
  switch (type) {
    case 'farmer':
      return FarmerWater
      break
    case 'jingtian':
      return JingTianWater
      break
    default:
      throw new Error('报错')
  }
}

let Farmer = getFactoryList('farmer')
let JingTian = getFactoryList('jingtian')
console.log(new Farmer('农夫山泉'))
console.log(new JingTian('景田矿泉水'))
// FarmerWater { type: 'farmer', typeName: '农夫山泉',list: ['农夫山泉1', '农夫山泉2', '农夫山泉3']}
// JingTianWater { type: 'jingtian', typeName: '景田矿泉水',list: ['景田矿泉水1', '景田矿泉水2', '景田矿泉水3']}

代理模式

介绍

  • 使用者无权访问目标对象
  • 中间加代理,通过代理做授权和控制
class RealImage {
  constructor(fileName) {
    this.fileName = fileName
    this.loadFromDisk()
  }

  display() {
    console.log('display...' + this.fileName)
  }

  loadFromDisk() {
    console.log('loading...' + this.fileName)
  }
}

class ProxyImage {
  constructor(fileName) {
    this.image = new RealImage(fileName)
  }

  display() {
    this.image.display()
  }
}

let img = new ProxyImage('a.png')
img.display()
// loading... a.png
// display... a.png

// ES6 Proxy
let star = {
  name: '张三',
  age: 25,
  phone: '13911119999'
}

let agent = new Proxy(star, {
  get: function(target, key) {
    if (key === 'phone') {
      // 返回经纪人电话
      return '13966662222'
    }
    if (key === 'price') {
      // 经纪人报价
      return 100000
    }
    return target[key]
  },
  set: function(target, key, val) {
    if (key === 'customPrice') {
      if (val < 100000) throw Error('价格太低')
    } else {
      target[key] = val
      return true
    }
  }
})

console.log(agent.phone) // 13966662222
console.log(agent.name)  // 张三
console.log(agent.price) // 100000

agent.customPrice = 110000
console.log(agent.customPrice) // 110000

单例模式

介绍

  • 系统中被唯一使用
  • 一个类只有一个实例
// 单例模式
class SingleDemo {
  constructor(name) {
    this.name = name
    this.instance = null
  }

  static getUserName(name) {
    if (!this.instance) this.instance = new SingleDemo(name)
    return this.instance
  }
}

let userA = SingleDemo.getUserName('张三')
let userB = SingleDemo.getUserName('李四')
console.log(userA === userB) // true

策略模式

// 策略模式
const A = salary => {
  return salary * 4
}

const B = salary => {
  return salary * 3
}

const C = salary => {
  return salary * 2
}

const D = salary => {
  return salary
}

const getLevelSalary = (level, salary) => {
  return level(salary)
}

console.log(getLevelSalary(A, 10000)) // 40000
上次更新: 8/31/2018, 5:52:20 PM