JavaScript 设计模式之享元模式
享元
将一部分共用的方法提取出来作为公用的模块
const Car = {getName: function () {return this.name},getPrice: function (price) {return price * 30}
}const BMW = function (name, price) {this.name = namethis.price = price
}
BMW.prototype = Car
const bmw = new BMW('BMW', 1000000)
console.log(bmw.getName()) // BMW
console.log(bmw.getPrice(1000000)) // 3000000const Benz = function (name, price) {this.name = namethis.price = price
}
Benz.prototype = Car
const benz = new Benz('Benz', 2000000)
console.log(benz.getName()) // Benz
console.log(benz.getPrice(2000000)) // 6000000
享元模式的应用目的是为了提高程序的执行效率与系统的性能。因此在大型系统开发中应用是比较广泛的,有时可以发生质的改变。它可以避免程序中的数据重复。有时系统内存在大量对象,会造成大量存占用,所以应用享元模式来减少内存消耗是很有必要的。
模板方法
假使我们有如下的样式
.panel {width: 200px;min-height: 50px;box-shadow: 0 0 10px rgba(0, 0, 0, .5);padding: 10px;margin: auto
}.btn-content {display: flex;justify-content: space-around;
}
.btn-content.right{flex-direction: row-reverse;
}
创建一个弹窗的基类
const Alert = function (data) {if (!data) returnthis.content = data.contentthis.panel = document.createElement('div')this.contentNode = document.createElement('p')this.confirmBtn = document.createElement('span')this.closeBtn = document.createElement('b')this.footerBtn = document.createElement('div')this.footerBtn.className = 'btn-content'this.panel.className = 'panel'this.confirmBtn.className = 'btn-confirm'this.closeBtn.className = 'btn-close'this.confirmBtn.innerHTML = data.confirm || '确认'this.closeBtn.innerHTML = data.close || '关闭'this.contentNode.innerHTML = data.content || ''this.success = data.success || function () { }this.cancel = data.cancel || function () { }
}Alert.prototype = {init: function () {this.panel.appendChild(this.contentNode)this.footerBtn.appendChild(this.confirmBtn)this.footerBtn.appendChild(this.closeBtn)this.panel.appendChild(this.footerBtn)document.body.appendChild(this.panel)this.bindEvent()this.show()},bindEvent: function () {this.confirmBtn.onclick = () => {this.success()this.hide()}this.closeBtn.onclick = () => {this.cancel()this.hide()}},show: function () {this.panel.style.display = 'block'},hide: function () {this.panel.style.display = 'none'}
}
基类主要用来实现一些常规的样式布局
定义一个标准的提示框
const TitleAlert = function (data) {Alert.call(this, data)this.title = data.titlethis.titleDom = document.createElement('h3')this.titleDom.style.textAlign = 'center'this.titleDom.innerHTML = this.titlethis.panel.className += ' title-panel'
}
TitleAlert.prototype = new Alert
TitleAlert.prototype.init = function () {this.panel.insertBefore(this.titleDom, this.panel.firstChild)Alert.prototype.init.call(this)
}
确认按钮位置在左/右
const LeftAlert = function (data) {TitleAlert.call(this, data)this.panel.className += ' left-panel'this.footerBtn.className += ' left'
}
LeftAlert.prototype = new Alert
LeftAlert.prototype.init = function () {TitleAlert.prototype.init.call(this)
}const RightAlert = function (data) {TitleAlert.call(this, data)this.panel.className += ' right-panel'this.footerBtn.className += ' right'
}
RightAlert.prototype = new Alert
RightAlert.prototype.init = function () {TitleAlert.prototype.init.call(this)
}
使用
new LeftAlert({title: '提示',content: '这是一个自定义的右上角弹窗',btnText: '确定',success: function () {console.log('点击了确定按钮');},cancel: function () {console.log('点击了取消按钮');}
}).init();
效果
模板方法的核心在于对方法的重用,它将核心方法封装在基类中,让子类继承基类的方法,实现基类方法的共享,达到方法共用。