前端设计模式 工厂模式
将new操作单独封装,遇到new时,就要考虑是否该用工厂模式
示例
你去购买汉堡,直接点餐,取餐,没必要自己亲手做(这就是一个初始化实例的封装)
商店要‘封装’做汉堡的工作,做好直接给买者
class Product { constructor(name) { this.name = name; } init() { alert('init'); } fn1() { alert('fn1'); } fn2() { alert('fn2'); } } class Creator{ create(name){ return new Product(name); } } // 测试 let creator = new Creator(); let p = creator.create('p1'); p.init(); p.fn1();
这个Creator就是个工厂,里面有create函数,工厂通过create函数创建product。这样通过create已经把真正的构造函数封装起来,外部只需要知道create能生成一个 实例就行
其他场景
jquery-$('div')
$('div')和new $('div')。会发现前面的工厂使用方便,如果每次都要加个new会比较麻烦。jQuery的链式操作将称为噩梦。一旦jquey名字变化,将是灾难性的。
class jQuery{ constructor(selector){ let slice = Array.prototype.slice; // 返回一个数组,将arguments对象的数组提出来转化为数组,arguments本身并不是数组而是对象 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) { } // 此处省略n个API } window.$ = function(selector) { return new jQuery(selector); } $p = $('p'); console.log($p); console.log($p.addClass);
return new jQuery(selector)。这个就是工厂模式,不开放出去。
React.createElement
var profile = ` <div> <img src='avatar.png' className='profile' /> <h3>{[user.firstName, user.lastName].join(' ')}</h3> </div> `
var profile = React.createElement('div', null, React.createElement('img', {src:'avatar.png', className:'profile'}), React.createElement('h3', null, [user.firstName, user.lastName].join(' ')) )
React.createElement就是一个工厂模式,后面实例我们不知道。被封装好了,想知道是什么,除非看源码
class Vnode { constructor(tag, attrs, children){ // ... } // ... } React.createElement = function (tag, attrs, children) { return new Vnode(tag, attrs, children) }
如果不是通过createElement,把new Vnode直接给用户,这样用户会比较麻烦
设计原则验证
1、构造函数和创建者分离
2、符合开放封闭原则