一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情。
导言
在《设计模式》成书之前,GoF原想把装饰器(decorator)模式称为包装器(wrapper)模式。从功能来说,装饰器模式更贴切,但如果从编码的结构上来说,更像是包装器。给对原始对象装饰时,其实是需要传入原始对象,再对原始对象进行修改。
装饰器模式和代理模式两者间的区别和用法一直也存在争议,有何不同吗?
拿个歌星来举例,我们假设歌星只想专注于做一件事情,那就是如何把歌唱好。那各种演唱会的社交活动就需要经纪人来安排是否参与,这里的经纪人就相当于是一个代理,商务活动由他来全权处理,歌星只做他自己的事;外部事物解决了,但歌星本星有个毛病就是记性差,老忘记歌词,这对唱好歌这件事也是影响很大的,又不是周杰伦,唱错几句歌迷都听不出来,所以得配个高级耳机来提词,这个高级耳机就是一个装饰器,让歌星能更好的唱歌。
现在懂了吧,代理模式一般是用来对原始对象访问的控制,而装饰器模式是为了完善对象而进行的修改。
装饰器模式
看了上面的解释,对装饰器模式应该有个大体了解了吧。现在,我们就以王者来举例。
// 召唤师典韦
let Dianwei = function (sm, wg, wk) {
this.sm = sm || 4000
this.wg = wg || 200
this.wk = wk || 100
}
Dianwei.prototype.harm = function () {
console.log(this.wg)
}
const dw = new Dianwei()
console.log(dw.wg) // 200
// 升级版典韦
let DianweiUpgrade = function (dw) {
dw.wg = 400
dw.harm()
}
const dwUp = new DianweiUpgrade(dw)
console.log(dwUp) // 400
升级版典韦构造函数DianweiUpgrade是通过传入初始版本对象,从而对原始对象进行操作,也就是对原始对象进行装饰和改造,让召唤师典韦拥有更强的杀伤力。在实际开发中也是一样,我们可以新增个装饰类或构造函数,在需要其特性时,用它来生成被装饰过的对象。