什么是装饰器?装饰器模式干了什么事情?
装饰器在我看来就是一个函数,该函数实现了对类、方法的扩展,提高了代码的复用性。
背景
某一天,我接到一个需求:写一个全局唯一的弹框(单例模式),点击后弹出文字'登录后查看'。话不多说开始编码:
// css html 忽略
// js如下
class Modal{
createInstance(){
// 如果没有实例,则创建一个实例赋值给 Modal.instance
if(!Modal.instance){
Modal.instance = document.createElement('div')
Modal.instance.id= "modal" // 元素id
Modal.instance.innerText = "登录后查看" // 元素内容
document.body.append(Modal)
}
// 如果存在实例,则直接返回
return Modal.instance
}
}
document.getElementById('open').addEventListener('click',()=>{
const modal = Modal.createInstance()
model.style.display = "block"
})
document.getElementById('close').addEventListener('click',()=>{
const modal = Modal.createInstance()
if(modal){
model.style.display = "none"
}
})
又来活了
代码平稳运行几天后,不料下个迭代又有一个关于这个需求:点击后需要把按钮的内容改为"去登录",且禁用该按钮
思考一下,如果使用装饰器模式,怎么实现?
ES5实现方式
// 把修改按钮和修改按钮的href的方法提成一个新方法
function openModal(){
const modal = Modal.createInstance()
model.style.display = "block"
}
function changeBtnStatus(){
const btn = document.getElementById('open')
btn.innerText = "去登录"
btn.setAttribute('disabled','true')
}
document.getElementById('open').addEventListener('click',()=>{
openModal()
changeBtnStatus()
})
ES6实现方式,面向对象
class Modal{
openModal(){
const modal = Modal.createInstance()
model.style.display = "block"
}
}
class BtnDecorator extends OpenBtn{
changeBtnStatus(){
const btn = document.getElementById('open')
btn.innerText = "去登录"
btn.setAttribute('disabled','true')
}
openModal(){
super.openModal()
this.changeBtnStatus()
}
}
document.getElementById('open').addEventListener('click',()=>{
const btnDecorator = new BtnDecorator()
btnDecorator.openModal() // 实现了修饰器的思想
})
推荐一个库
core-decorators,实现了许多的装饰器以供使用。