Skip to content

介绍

  • 将new操作单独封装
  • 遇到new时,就要考虑是否该使用工厂模式

示例

  • 你去购买汉堡,直接点餐、取餐,不会自己亲手做
  • 商店要“封装”做汉堡的工作,做好直接给买者

常见使用场景

  • jQuery的函数$(),内部创建了新对象
    • ('div') 与 new ('div')有何区别?
    • 第一:书写麻烦,jQuery的链式操作将成为噩梦
    • 第二:一旦类名jQuery发生变化,将是灾难性的
javascript
class jQuery {
  constructor(selector) {
    let slice = Array.prototype.slice
    let dom = slice.call(document.querySelectorAll(selector))
    let len = dom ? dom.length : 0
    for (let i = 0; i < len; i++) {
      this[i] = dom[i]
    }
    this.length = len
    this.selector = selector || ''
  }
  append(node) {}
  addClass(name) {}
  html(data) {}
  // coding...
}
window.$ = function (selector) {
  return new jQuery(selector)
}

// test
var $p = $('p')
console.log($p)
console.log($.addClass)
  • React.createElement
javascript
// jsx语法
var profile = (
	<div>
		<img src="avatar.png" className="profile" />
		<h3>{[user.firstName, user.lastName].join("")}</h3>
	</div>
);

// react手写dom
var profile = React.CreateElement(
	"div",
	null,
	React.CreateElement("img", { src: "avatar.png", className: "profile" }),
	React.CreateElement("h3", null, [user.firstName, user.lastName].join(" "))
);

// react内部代码
class Vnode(tag, attrs, children) {
  // Coding...
}
React.CreateElement = function (tag, attrs, children) {
	return new Vnode(tag, attrs, children);
};
  • vue异步组件
javascript
Vue.component('asycn-example', function (reslove, reject) {
  setTimeout(function () {
    reslove({
      template: '<div>I am async!</div>',
    })
  })
})

工厂模式代码示例

javascript
class Product {
  constructor(name) {
    this.name = name
  }

  init() {
    alert('init')
  }

  fun1() {
    alert('fun1')
  }

  fun2() {
    alert('fun2')
  }
}

class Creator {
  create(name) {
    return new Product(name)
  }
}

// test
let creator = new Creator()
let p = creator.create('p1')
p.init()
p.fun1()

总结

工厂模式主要用在需要频繁创建新对象的时候,以及多处需要创建新对象的时候。 使用工厂模式可以避免类名改动造成需要大量修改代码的情况