php装饰器模式 简书,装饰器模式

1.装饰器模式,它的定义是“在不改变元对象的基础上,通过对其包装拓展,是原有对象可以满足用的更复杂需求。”

比如水墨屏的手机壳,就是一个标准的装饰器,它不会对手机原有的功能产生任何影响,仅仅使手机多了块屏幕。

2.为什么会有装饰器模式?

因为任何人在去做需求的时候,都不想关心它现有的业务逻辑是什么样的,只想对它已有的功能做拓展,只关心拓展功能如何实现。于是便有了装饰器模式。

3.装饰器怎么实现?

首先,将旧逻辑与新逻辑分离,把旧逻辑封装起来。

然后编写新逻辑。

最后把新逻辑旧逻辑整合到一起。

ES5的实现

document.getElementById('open').addEventListener('click', function() {

openModal() // 旧逻辑

changeButtonStatus() //新逻辑

})

ES6的实现

// 定义打开按钮

class OpenButton {

// 点击后展示弹框(旧逻辑)

onClick() {

const modal = new Modal()

modal.style.display = 'block'

}

}

// 定义按钮对应的装饰器

class Decorator {

// 将按钮实例传入

constructor(open_button) {

this.open_button = open_button

}

onClick() {

this.open_button.onClick()

// “包装”了一层新逻辑

this.changeButtonStatus()

}

changeButtonStatus() {

this.changeButtonText()

this.disableButton()

}

disableButton() {

const btn = document.getElementById('open')

btn.setAttribute("disabled", true)

}

changeButtonText() {

const btn = document.getElementById('open')

btn.innerText = '快去登录'

}

}

const openButton = new OpenButton()

const decorator = new Decorator(openButton)

document.getElementById('open').addEventListener('click', function() {

// openButton.onClick()

// 此处可以分别尝试两个实例的onClick方法,验证装饰器是否生效

decorator.onClick()

})

4.ES7的装饰器函数

可装饰类,也可装饰类里面的方法

// 将装饰器“安装”到Button类上

@classDecorator

class Button {

// Button类的相关逻辑

}

//装饰类的方法

class Button {

@funcDecorator

onClick() {

console.log('我是Func的原有逻辑')

}

}

5.装饰器语法糖帮我们做了些什么

(1)函数传参&调用

给类添加装饰器时,target是被装饰的类本身

function classDecorator(target) {

target.hasDecorator = true

return target

}

给方法添加装饰器时,target变成了类的原型对象。

function funcDecorator(target, name, descriptor) {

let originalMethod = descriptor.value

descriptor.value = function() {

console.log('我是Func的装饰器逻辑')

return originalMethod.apply(this, arguments)

}

return descriptor

}

装饰器函数调用的时机:装饰器函数在编译阶段就执行了。

(2)传入“属性描述对象”descriptor

对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。

它由各种各样的属性描述符组成,这些描述符又分为数据描述符和存取描述符:

数据描述符:包括 value(存放属性值,默认为默认为 undefined)、writable(表示属性值是否可改变,默认为true)、enumerable(表示属性是否可枚举,默认为 true)、configurable(属性是否可配置,默认为true)。

存取描述符:包括 get 方法(访问属性时调用的方法,默认为 undefined),set(设置属性时调用的方法,默认为 undefined )

拿到了 descriptor,就相当于拿到了目标方法的控制权。通过修改 descriptor,我们就可以对目标方法的逻辑进行拓展了~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值