javascript 设计模式之简单工厂模式

简单工厂

对于有许多的不同功能的方法时,又想将其变得共用,这时候简单工厂模式就发挥了重大作用

const Dog = function () { 
  this.species = "犬科";
  this.name = "孙子"
};
const Cat = function () {
  this.species = "猫科";
  this.name = "小强"
}

// 简单工厂模式
const animateFactory = function (name) { 
  switch (name) { 
    case "Dog":
      return new Dog();
    case "Cat":
      return new Cat();
    default:
      return null;
  }
}

const dog = animateFactory("Dog") // { species: '犬科', name: '孙子' }
const cat = animateFactory("Cat") // { species: '猫科', name: '小强' }

安全模式

首先,我们需要保证一个函数的安全,比如

1、不安全

const Fun = function (name) {
  this.name = name
  this.showName = function(){
    return this.name
  }
}

const fun = new Fun("方人智")
console.log(fun.showName()) // 方人智

// 但是当我们可能忽略 new 关键字时,问题就出来了

const fun1 = Fun("陈歪嘴") // Cannot set properties of undefined
console.log(fun1.getName())  // 这里就不能调用这个方法

这时,我们可以这样来改造下这个方法,使其变得安全

2、安全改进

const Fun = function (name) {
  // 在这里做一个判断,当 this 不是 Fun 的实例时,我们帮他 new 一下
  if (!(this instanceof Fun)) { 
    return new Fun(name);
  }
  this.name = name
  this.showName = function(){
    return this.name
  }
}

const fun1 = Fun("陈歪嘴")
console.log(fun1.showName()) // 陈歪嘴

安全工厂

实际上只是将安全模式给添加到工厂模式中而已

// 安全的工厂函数
const SuperFactory = function (type, content) {
  if (this instanceof SuperFactory) {
    return new this[type](content)
  } else {
    return new SuperFactory(type, content)
  }
}

SuperFactory.prototype = {
  Dog: function (name) {
    // todo:
    this.name = name
  },
  Cat: function (name) {
    // todo:
    this.name = name
  }
}

const dog = SuperFactory("Dog", "汪汪")
const cat = new SuperFactory("Cat", "喵喵")
console.log(dog.name) // 汪汪
console.log(cat.name) // 喵喵

抽象工厂

抽象,也就是子类必须要重写父类中的方法才能调用,而不能直接调用父类中的抽象方法,这里面我们在定义工厂基类时使用寄生方式

const VehicleFactory = function (type, superType) {
  if (typeof VehicleFactory[superType] === "function") {
    function F() { }
    F.prototype = new VehicleFactory[superType]()
    type.constructor = type
    type.prototype = new F()
  }
}
VehicleFactory.Dog = function () {
  this.type = "dog"
}
VehicleFactory.Dog.prototype = {
  getName: function () {
    return new Error('抽象方法不能被调用')
  },
  getType: function () {
    return new Error('抽象方法不能被调用')
  }
}

VehicleFactory.Cat = function () {
  this.type = "cat"
}
VehicleFactory.Cat.prototype = {
  getName: function () {
    return new Error('抽象方法不能被调用')
  }
}

const Dog = function (name) {
  this.name = name;
}
VehicleFactory(Dog, "Dog")
Dog.prototype.getName = function () {
  return this.name;
}
Dog.prototype.sound = function () {
  return "汪汪汪"
}
const Cat = function (name) {
  this.name = name;
}
VehicleFactory(Cat, "Cat")
Cat.prototype.getName = function () {
  return this.name;
}
const dog = new Dog("旺财");
const cat = new Cat("Tom");
console.log(cat.getName()); // Tom
console.log(dog.getName()); // 旺财
console.log(dog.sound()); // 汪汪汪
console.log(dog.getType()); // Error: 抽象方法不能被调用

你可能感兴趣的:(JavaScript设计模式,javascript,设计模式,简单工厂模式)