工厂模式

简单工厂模式

定义:简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
关于简单工厂我看了很多文档,依旧没有消除我的疑惑(构造函数是否是简单工厂???)
因此,我在下面的文档中会把构造函数也放入简单工厂中(如果我的理解有误,还望海涵)

// 因为在我的认知中, 构造函数和下面的方法唯一的区别就是是否能找到创建这个对象的方法
// 构造函数
function SingleFactory(name) {
  this.name = name
}
// 简单工厂
// 传入参数,创建相应实例
function singleFactory(name) {
  return new Object({ name })
}
const sfp = new SingleFactory('小猫')
const sf = singleFactory('小狗')
console.log(sfp) //SingleFactory {name: '小猫'}
console.log(sf) // {name: '小狗'}

工厂方法模式

定义:工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
在工厂方法中,我们只需要维护工厂方法的属性,就可以实现不同的类

function Animals(name) {
  return new this[name]()
}
Animals.prototype = {
  Cat: function () {
    this.animals = ['橘猫', '狸花猫']
  },
  Dog: function () {
    this.animals = ['中华田园犬', '凶猛大藏獒']
  },
}

var dog = new Animals('Dog')
var cat = new Animals('Cat')
console.log(dog) // Dog {animals: Array(2)}
console.log(cat) // Cat {animals: Array(2)}

当然按照我的理解,我们不仅需要支持 new 的构造函数的写法,依然要支持函数调用的形式,把上面的代码调整一下。

function Animals(name) {
  if (this instanceof Animals) {
    return new this[name]()
  } else {
    return new Animals(name)
  }
}
Animals.prototype = {
  Cat: function () {
    this.animals = ['橘猫', '狸花猫']
  },
  Dog: function () {
    this.animals = ['中华田园犬', '凶猛大藏獒']
  },
}

var dog = new Animals('Dog')
var cat = Animals('Cat')
console.log(dog) // Dog {animals: Array(2)}
console.log(cat) // Cat {animals: Array(2)}

这样,我们就支持 new 去构造一个对象或者直接调用函数去构造一个对象

抽象工厂模式

定义:抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象

function Animals(subType, superType) {
  if (typeof Animals[superType] === 'function') {
    // 这里其实有个知识点, 构造函数的几种继承方式,这里使用的是最合理的组合寄生继承,当然本文不会去详解继承的方式
    // 用来继承父类的容器
    var F = function () {}
    // F 函数的原型指向 Animals 子类的实例
    F.prototype = new Animals[superType]()
    // subType 子类的构造器指向自身
    subType.constructor = subType
    // subType 子类的原型指向父类
    subType.prototype = new F()
  } else {
    throw new Error('Animals 没有该抽象类')
  }
}
Animals.Cat = function () {
  this.type = '小猫'
}
Animals.Cat.prototype = {
  execVoice: function () {
    return new Error('该方法需要被重写')
  },
}
Animals.Dog = function () {
  this.type = '小狗'
}
Animals.Dog.prototype = {
  execVoice: function () {
    return new Error('该方法需要被重写')
  },
}
function Dog(name, voice) {
  this.name = name
  this.voice = voice
}
function Cat(name, voice) {
  this.name = name
  this.voice = voice
}
Animals(Dog, 'Dog')
Animals(Cat, 'Cat')
Dog.prototype.execVoice = function () {
  return this.voice
}
Cat.prototype.execVoice = function () {
  return this.voice
}
var dog = new Dog('旺财', '汪汪汪')
var cat = new Cat('思乡', '喵喵喵')
console.log(dog, dog.execVoice()) // Dog '汪汪汪'
console.log(cat, cat.execVoice()) // Cat '喵喵喵'

你可能感兴趣的:(javascript前端)