JavaScript 设计模式之工厂模式

422 阅读4分钟

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

前言

在实际开发中,不发生变化的代码可以说是不存在的。我们能做的只有将这个变化造成的影响最小化 —— 将变与不变分离,确保变化的部分灵活、不变的部分稳定。

上面说的这个过程,就叫“封装变化”;这样的代码,就是我们所谓的"健壮"的代码,它可以经得起变化的考验。设计模式,其实就是一些套路,帮助我们写出这样的代码。工厂模式,做的事情就是将创建对象的过程抽离,今天我们来聊聊工厂模式。

简单工厂模式

工厂模式映射我们日常生活中的工厂,工厂是用来干嘛的呢?是用来生产产品的,对应到代码当中,就是能够帮我们生成不同实例的函数。

上面说到生成不同实例的函数,就是构造函数的方式。

我们来看看这个代码,看看熟悉不:

function createPerson(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}

const person = new createPerson('追梦玩家', 18, 'male');
console.log(person);

当然也可以不用 new 的方式,改成:

function createPerson(name, age, sex) {
  let obj = {};
  obj.name = name;
  obj.age = age;
  obj.sex = sex;
  return obj;
}

const person = createPerson('追梦玩家', 18, 'male');
console.log(person);

复杂工厂模式

复杂工厂模式:当我们的属性和方法足够多,我们希望提供一个公共类,也就是提供一个父类,让子类能够继承父类的属性和方法,从而达到抽象的目的。

也就是说我们现在希望能够有一个父类,子类去继承父类上面的属性和方法。每一个子类,能够实现自己的实例方法。

也就是说父类解决的是,一般性的问题,而子类解决的是具体的问题。

  1. 父类:是一个抽象类,不可以直接实例
  2. 子类实现自身的实例方法

上面说的,可能有点不太好理解。我们来举个例子:

现在会有这样一个工厂,自行车的商店,它能够有一个名字,然后有一个方法,能够获取到商店的名字。

自行车商店,可以理解成父类,是抽象类,它是用来干嘛的呢?它是用来卖单车的,自行车商店,不负责产出自行车。

function BicycleShop(name) {
  this.name = name;
  this.method = function () {
    return this.name;
  }
}

BicycleShop.prototype = {
  constructor: BicycleShop,
  sellBicycle: function () {
    var bicycle = this.CreateBicycle();

    bicycle.a();
    bicycle.b();

    return bicycle;
  },
  CreateBicycle: function () {
    throw new Error('父类不能直接实例,需要子类来实例');
  }
}

上面说到子类去继承父类的属性和方法,那么 ES6 之前,如何实现继承呢?可以使用下面这个方法: Sub 是子类,Sup 是父类

function extend(Sub, Sup) {
  var F = function() {};
  F.prototype = Sup.prototype;
  Sub.prototype = new F();
  Sub.prototype.constructor = Sub;
}

实现子类,需要使用 extend 方法实现子类继承父类

子类怎么拿到父类的属性和方法,通过怎么样的方式呢?通过 call 方法,借用父类的构造函数。

function BicycleChild(name) {
  this.name = name;
  BicycleShop.call(this, name);
}

extend(BicycleChild, BicycleShop);

BicycleChild.prototype.createBicycle = function () {
  var a = function () {
    console.log('执行 a 任务');
  };
  var b = function () {
    console.log('执行 b 任务');
  };

  return {
    a,
    b
  }
}

var bicycleChild = new BicycleChild('凤凰');
console.log(bicycleChild);
console.log(bicycleChild.createBicycle());
console.log(bicycleChild.sellBicycle());

输出结果:

image.png

复杂工厂模式,能够实现在父类当中定义抽象的方法,我们可以把方法给抽象出来,子类可以实现自己的业务逻辑。

从专业来说,就是弱化代码之间的耦合,也就是当父类或者工厂模式当中的属性或者方法更多的话,我们就需要通过这样的方式来减少代码的耦合,弱化对象的耦合,防止代码的重复。

复杂代码,我们就可以把它扔到父类当中,然后子类就继承父类的所有属性和方法,那子类只需要做自己的业务逻辑就可以了。

写到最后

设计模式,其实就是一些套路,帮助我们写出这样的代码。工厂模式,做的事情就是将创建对象的过程抽离。

文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你或者喜欢,欢迎点赞和关注。