装饰器模式是一种结构型设计模式,它允许你在不改变对象结构的情况下,动态地给对象添加新的行为或职责。
装饰器模式通过创建一个装饰器
类,来包装原始对象,并在不改变原始对象的基础上,为其添加新的功能。装饰器类和原始对象实现相同的接口
,因此可以互相替换
。
优点
是可以在不改变原始对象的情况下,动态地添加新的功能,从而提高代码的灵活性和可维护性。
同时,装饰器模式也可以避免在原始对象中添加过多的功能,从而提高代码的可读性和可维护性。
缺点
是会增加代码的复杂性,并且可能会影响代码的性能。因此,在使用装饰器模式时,需要谨慎考虑,并根据具体情况选择合适的设计模式。
运用
设我们的初始需求是:每个业务中的按钮在点击后都弹出「您还未登录哦」的弹窗。
产品经理说这个弹窗提示还不够明显,我们应该在弹窗弹出后把按钮的文案改为“快去登录”,同时把按钮置灰。
<body>
<div class="box">
<button id="open">打开弹窗</button>
<button id="close">关闭弹窗</button>
</div>
<script>
//源代码
const open = document.getElementById('open')
const close = document.getElementById('close')
const box = document.querySelector('.box')
const Modal = (function () {
let instance = null
return () => {
if (!instance) {
instance = document.createElement('div')
instance.innerHTML = '内容'
instance.className = 'modal'
instance.style.display = 'none'
box.appendChild(instance)
}
return instance
}
})()
function openModal() {
const modal = Modal()
modal.style.display = "block"
}
class OpenBtn {
onClick() {
const modal = Modal()
modal.style.display = "block"
}
}
class Decorator {
constructor(openBtn) {
this.openBtn = openBtn
}
onClick() {
//旧逻辑
this.openBtn.onClick()
//新逻辑
this.changeBtn()
}
changeBtn() {
open.innerText = '快去登录'
open.setAttribute('disabled', true)
}
}
const openBtn = new OpenBtn()
const decorator = new Decorator(openBtn)
open.addEventListener('click', () => {
decorator.onClick()
})
</script>
</body>
装饰器语法糖
// 装饰器函数,它的第一个参数是目标类
function classDecorator(target) {
target.hasDecorator = true
return target
}
// 将装饰器“安装”到Button类上
@classDecorator
class Button {
// Button类的相关逻辑
}
// 验证装饰器是否生效
console.log('Button 是否被装饰了:', Button.hasDecorator)