设计模式之Factory

Factory模式和它的名字一样,是一个可以像工厂那样用来批量生产对象的函数。其实在JS中类似用途的方法有许多,比如ES5中就已经有的constructor,还有ES6中还添加了class。那为什么还要大费周章地发明factory呢?

让我们先来看看ES6的class方法:

class Dog {
  constructor() {
    this.sound = 'woof'
  }

  talk() {
    console.log(this.sound)
  }
}

const sniffles = new Dog()
sniffles.talke()    // woof

看起来好像一切很美好,但是事情总不会那么顺利。我们都知道,JS中的this指的并不是对象本身,而是该方法的实际调用者。于是在某些情况下,sniffles.talke中的this.sound会因为this的问题而出错:

$('button.myButton).click(sniffles.talk)

这里的this其实是myButton,所以无法正确取得this.sound成员。当然了,我们可以用bind、apply来绑定this,但非常不自然。使用factory模式就可以很好地解决这个问题,而且代码页更清晰简洁:

const dog = () => {
  const sound = 'woof'

  return {
    talk: () => console.log(sound)
  }
}

const sniffles = dog()
sniffles.talk()    //woof

这样一来,我们的代码$('button.myButton).click(sniffles.talk)就不会有问题了,因为在factory中根本没有使用this。此外,sound处于closure中,等同于一个私有对象,只有dog内部成员能访问它。于是我们又借此实现了encapsulation。

Factory模式使用更少、更简洁的代码实现了同样的功能,那它是否是class或constructor的完美替代者呢?实际上class由于内建语法支持,更容易得到编译器的优化,使其创建效率比factory要高。在本地电脑商测试,factory创建对象耗时约为0.0004ms,而class耗时约为0.0002ms,class要快50%!

我个人认为,如果你需要在单一场景中创建大量的对象(上千个对象),或是追求执行效率的场景(游戏、图像处理等),还是采用class吧。但对大多数应用来说,factory更简洁优雅,同时也避免了许多不易察觉的问题,就放心使用吧!

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