JS设计模式

39 设计模式

设计模式可以分为三大类:

  1. 结构型模式:通过识别系统中组件间的简单关系来简化系统色设计
  2. 创建型模式:处理对象的创建,根据实际情况使用合适的方式创建对象
  3. 行为型模式:用于识别对象之间常见的交互模式并加以实现,如此增加了这些交互的灵活性。

39.1 工厂模式

说明:你可以想象一个场景,假设有一份很复杂的代码需要用户去调用,但是用户并不关心这些复杂的代码,只需要你提供一个接口去调用,用户只负责传递需要的参数,至于这个参数怎么使用,内部逻辑不用关心,只需要你最后返回一个实例,这个构造过程就是工厂。
工厂起到的作用就是隐藏了创建实例的复杂度,只需要一个接口,简单清晰。

现实生活中的工厂按照既定的程序制造产品,随着生产原料和流程不同生产出来的产品也会有区别。应用到软件工厂的领域,工厂可以看成是一个制造其他对象的对象,制造出来的对象也会随着传入共产对象的参数的不同而有所区别
那么,什么时候适合使用共产模式而不是直接new一个对象呢?当构造函数过多不便管理,且需要创建的对象之间存在某些关联(有同一个父类,实现同一个接口)时,不妨使用工厂模式,工厂模式提供一种集中化,统一化的方式,避免了分散创建对象导致的代码重复、灵活性差的问题。

举例如下:(构造一个简单的汽车工厂来生产汽车)

//汽车构造函数
function Car1(color) {
  this.color = color
  this.brand = 'Car1'
}

//汽车构造函数
function Car2(color) {
  this.color = color;
  this.brand = 'Car2'
}

//汽车构造函数
function Car3(color) {
  this.color = color;
  this.brand = 'Car3'
}

//汽车的品牌
const BRANDS = {
  car1: 1,
  car2: 2,
  car3: 3
}

//汽车工厂
function createCar() {
  this.create = function (brand, color) {
    switch (brand) {
      case BRANDS.car1:
        return new Car1(color);
      case BRANDS.car2:
        return new Car2(color);
      case BRANDS.car3:
        return new Car3(color);
      default:
        break;
    }
  }
}


//测试
const carFactory = new createCar();
const cars = [];

cars.push(carFactory.create(BRANDS.car1, 'red'))
cars.push(carFactory.create(BRANDS.car2, 'greed'))
cars.push(carFactory.create(BRANDS.car3, 'pink'))

function say() {
  console.log(`Hi , I am ${this.color} and ${this.brand} car`)
}

for (const car of cars) {
  say.call(car)
}

结果如下

使用工厂模式后,不再需要重复引入一个个构造函数,只需要引入工厂对象便可以创建各类对象

39.2 单例模式

单例模式的核心就是保证全局只有一个对象可以访问,Class的实例个数最多为1,一般全局缓存、全局状态管理等待这些只需要一个对象,就可以使用单例模式。 即我们只需要用一个变量确保实例只创建一次就可以,以下为其实例:

class Singleton {
  constructor() {
  }
}
Singleton.getInstance = (function () {
  let instance;
  return function () {
  //这里使用的闭包,使用闭包保存局部作用域中的单例对象并返回
    if (!instance) {
      instance = new Singleton();
    }
    return instance;
  }
})()

let s1 = new Singleton.getInstance();
let s2 = new Singleton.getInstance();
console.log(s1 === s2) //true

设计思路:即当instance为空时,则new创建新对象,若不为空时返回原来的instance对象,因此使得每次都是同一个对象

39.3 代理模式

代理是为了控制对对象的访问,不让外部直接访问到对象,也有很多代理的场景。比如事件代理就用到了代理模式。

  
  • 1
  • 2
  • 3
  • 4
  • 5

因为存在太多的li,不可能内个都去绑定事件,这时可以通过给父节点绑定一个事件,让父节点作为代理去拿到真实点击的节点。

39.4 发布-订阅者模式

发布-订阅者模式也叫作观察者模式。通过一对一或者一对多的依赖关系,当对象发生改变时,订阅方也会收到通知。

在现实生活中如商品缺货时点击有货通知的按钮
在实际代码中如我们点击一个按钮触发了点击事件就是使用了观察者模式

  let ul = document.querySelector('#ul');
    ul.addEventListener('click', function (event) {
      console.log(event.target)
    })

39.5 外观模式

外观模式提供一个接口,隐藏了内部的逻辑,更加方便外部调用
比如兼容多个浏览器添加时间就是使用外观模式

function addEvent(ele, ebType, fn, useCapture) {
  if (ele.addEventListener) {
    ele.addEventListener(evType, fn, useCapture);
    return true
  } else if (ele.attachEvent) {
    var r = ele.attachEvent("on" + evType, fn)
    return r;
  } else {
    //均支持这种事件绑定方式
    ele["on" + evType] = fn
  }
}

对于不同浏览器,添加的事件的方式可能会存在兼容问题。如果诶次都需要去这样写一遍的话肯定是不能接受的,所以我们将这些判断逻辑统一封装在一个接口中,外部需要添加时间时只需要调用addEvent即可。
————————————————
原文链接:https://blog.csdn.net/weixin_46872121/article/details/111936904

你可能感兴趣的:(JS设计模式)