浅浅了解设计模式之一 | 创建型

130 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

为什么要了解设计模式?

当然是因为面试要问啦

啊不是

23种太多,先了解其中5种吧

image.png

创建型:创建对象的设计模式

单例模式

单例的特点就是只有一个实例,并且可以全局访问

  // 这里的instance相当于一个单例
  let Singleton = function () {
    this.instance = null
  }
  
  Singleton.getInstance = function (instance) {
    if (this.instance) {
      return this.instance;
    }
    this.instance = instance;
    return this.instance;
  }
  
  console.log(Singleton.getInstance({ name: 'zhangsan' })); // {name: 'zhangsan'}
  console.log(Singleton.getInstance({ name: 'lisi' })); // {name: 'zhangsan'}

当我们需要的时候才创建实例,可以提高网页性能,加快渲染速度

原型模式

GoF将原型模式引用为通过克隆的方式基于一个现有对象的模板创建对象的模式

这里的克隆也仅限于浅浅的克隆一下

  let o = {
    name: 'zhangsan',
    feature: {
      like: 'ball'
    }
  }
  let o1 = Object.create(o);
  o1.feature.like = 'water';
  
  console.log(o.feature, o1.feature); // {like: 'water'} {like: 'water'}
  console.log(o.feature === o1.feature); // true

可以使用Object.create提供第二个参数为创建出来的对象添加属性,实现继承

构造器模式

使用构造器创建对象,初始化对象的属性和方法

  // 创建对象
  let o1 = {}
  let o2 = Object.create(null);
  let o3 = new Object();
  
  // 赋值属性和方法
  o1.name = 'zhangsan';
  o1['age'] = 12;
  o1.fun = () => {
    console.log('我是一个方法');
  }
  Object.defineProperty(o1, 'sex', {
    value: '男'
  });

如上所示,js没有类的概念,要想有可以直接new出来一个通用的构造器,就需要写一个函数来当作构造器来使用

  // 构造器
  function Car(name) {
    this.name = name;
    this.fun = () => {
      console.log('我是一个方法');
    }
  }
  // 原型上有的函数可以用prototype取代
  Car.prototype.toString = function () {
    return this.name;
  }
  
  const car = new Car('我是一辆车');

工厂模式

根据需求创建想要的对象 比如有一个ui工厂,提供table和form两个组件,只需要告诉工厂需要的组件类型,就可以获得对应的组件

  function Table() {
    this.name = 'table'
  }
  function Form() {
    this.name = 'form'
  }
  
  function UIFactory() { }
  UIFactory.prototype.type = null;
  UIFactory.prototype.createUI = function (type) {
    if (type === 'table') {
      this.type = Table
    } else {
      this.type = Form
    }
    return new this.type();
  }

  const myUi = (new UIFactory()).createUI('table');
  console.log(myUi); // Table {name: 'table'}

抽象工厂模式

  • 工厂定义好函数,开放两个api
  • 一个用于注册组件
  • 一个用于创建组件
  // 抽象工厂
  let AbstractUIFactory = (function () {
    let uis = {};
    return {
      registerUI: function (key, value) {
        uis[key] = value;
      },
      getUI: function (type) {
        return new uis[type]();
      }
    }
  })();
  
  // 注册组件
  AbstractUIFactory.registerUI('table', Table);
  AbstractUIFactory.registerUI('form', Form);
  
  // 创建组件
  let table = AbstractUIFactory.getUI('table', Table);
  let form = AbstractUIFactory.getUI('form', Form);
  
  console.log(table, form);
  // Table {name: 'table'} Form {name: 'form'}

参考文章# JavaScript 设计模式