JavaScript常用设计模式

设计模式主要分为3类:
1、创建型设计模式:专注于处理对象的创建

Constructor构造器模式,Factory工厂模式,Singleton单例模式,builder生成器模式

2、结构型设计模式:对象间组合,建立对象之间的关系

Decorator装饰者模式,Facade外观模式,Flyweight享元模式,Adapter适配器模式,Proxy代理模式

3、行为设计模式:简化和改善对象间的通信

Mediator中介者模式,Observer观察者模式

一、 单例模式

单例模式限制一个类只有一个实例化对象。

// 利用闭包实现
var Leader = (()=>{
    let _instance = null;
    // 待实例化的类
    function _module(){
        this.name = '';
        this.getName = ()=>{
            return 'The Name Is ' + this.name;
        }
        this.setName = (name) => {
            this.name = name;
        }
    }

    return {
        getInstance:()=>{
            if(!_instance){
                _instance = new _module();
            }
            return _instance;
        }
    }
})();
Leader.getInstance().setName('dzk')
Leader.getInstance().getName()
二、观察者模式

一个目标对象维持着一系列依赖于它的对象,将有关状态的任何变更自动通知观察者们。在观察者模式中,观察者需要直接订阅目标对象,观察者与目标对象之间有一定的依赖关系。

// 目标对象
class Subject {
  constructor() {
    // 观察者列表
    this.observers = []
  }
  addObserver(observer) {
    this.observers.push(observer)
  }
  removeObserver() {
    this.observers.pop()
  }
  notify() {
    this.observers.forEach(observer => {
      observer.update()
    })
  }
}

// 观察者1
class Observer1 {
  update() {
      console.log('Observer1 change!')
   }
}
// 观察者2
class Observer2 {
  update() {
      console.log('Observer2 change!')
   }
}
// 订阅
let curSubject = new Subject()
let curObserver1 = new Observer1()
let curObserver2 = new Observer2()
curSubject.addObserver(curObserver1)
curSubject.addObserver(curObserver2)
// 触发
curSubject.notify()
三、发布/订阅模式

发布订阅模式可以说是观察这模式的一种变体,一种实现。它使用一个主题/事件通道,介于发布者和订阅者之间,避免了发布者和订阅者之间的依赖关系。

class PubSub {
  constructor() {
    // 主题/事件通道
    this.topics = {}
  }
  publish(topic, args) {
    if (!this.topics[topic]) {
      return
    }
    let subscribers = this.topics[topic]
    subscribers.forEach(subscriber => {
        subscriber(args)
    })
  }
  subscribe(topic, subscriber ) {
    if (!this.topics[topic]) {
      this.topics[topic] = []
    }
    this.topics[topic].push(subscriber )
  }
}
// 接收函数1
let subscriber1 = (reData) => {
    console.log('subscriber1', reData)
}
// 接收函数2
let subscriber2 = (reData) => {
    console.log('subscriber2', reData)
}

let pubsub = new PubSub()

pubsub.subscribe('reEvent', subscriber1 )
pubsub.subscribe('reEvent', subscriber2 )
pubsub.publish('reEvent', '通知了')
四、工厂模式

工厂函数提供一个通用的接口来创建对象,我们可以指定我们希望创建的对象类型,我们通知工厂函数需要什么类型的对象并提供对应的数据,返回对应的实例。

class Car {
  constructor(options) {
    // ...
  }
}

class Truck {
  constructor(options) {
      // ...
  }
}

function vehicleFactory (options) {
  if (options.type === 'car') {
    return new Car(options)  
  } else {
    return new Truck(options)
  }
}
let getInstance = vehicleFactory({type: 'car',name: 'xxx'})
五、抽象工厂模式

抽象工厂模式,将对象的实现细节抽离出来。适用于需要和多种对象一起工作的场景。

class Car {
  constructor(options) {
    // ...
  }
}

class Truck {
  constructor(options) {
      // ...
  }
}

class AbstractFactory {
  constructor() {
    this.types = {}
  }
  registerFactory(type, factory) {
    this.types[type] = factory
  }
  getInstance(type, args) {
    let factory = this.types[type]
    if (factory) {
      return new factory(args)
    }
  }
}

let abstractFactory = new AbortController()
abstractFactory.registerFactory('car', Car)
abstractFactory.registerFactory('truck', Truck)

abstractFactory.getInstance('car', options)
abstractFactory.getInstance('truck', options)

上一篇
迭代器(Iterator)和生成器(Generator) 迭代器(Iterator)和生成器(Generator)
一、迭代器概念: 迭代器是一个统一的接口,它的作用是使各种数据结构可被便捷的访问,它是通过一个键为Symbol.iterator 的方法来实现。 迭代器是用于遍历数据结构元素的指针(如数据库中的游标)。 实现过程: 通过 Symbol.i
2020-12-07
下一篇
盒子模型,行内元素边距,置换元素 盒子模型,行内元素边距,置换元素
一、 盒子模型 box-sizing: content-box;//宽度和高度分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距和边框。 box-sizing: border-box;// 怪异盒子模型。 为元素设定的宽度和高度决
2020-09-09