装饰器模式是一种结构型设计模式,它允许你在不改变对象结构的情况下,动态地给对象添加新的行为或职责。
装饰器模式通过创建一个装饰器
类,来包装原始对象,并在不改变原始对象的基础上,为其添加新的功能。装饰器类和原始对象实现相同的接口
,因此可以互相替换
。
优点
是可以在不改变原始对象的情况下,动态地添加新的功能,从而提高代码的灵活性和可维护性。
同时,装饰器模式也可以避免在原始对象中添加过多的功能,从而提高代码的可读性和可维护性。
缺点
是会增加代码的复杂性,并且可能会影响代码的性能。因此,在使用装饰器模式时,需要谨慎考虑,并根据具体情况选择合适的设计模式。
运用
设我们的初始需求是:每个业务中的按钮在点击后都弹出「您还未登录哦」的弹窗。
产品经理说这个弹窗提示还不够明显,我们应该在弹窗弹出后把按钮的文案改为“快去登录”,同时把按钮置灰。
<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 = nullreturn () => {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 = truereturn target
}// 将装饰器“安装”到Button类上
@classDecorator
class Button {// Button类的相关逻辑
}// 验证装饰器是否生效
console.log('Button 是否被装饰了:', Button.hasDecorator)