前言
同学们,上一章节我们介绍了中介者模式,中介者模式应用于对象关系复杂的场景,将所有对象之间的交互集中到中介对象处,来降低对象之间的耦合性,这一章节,我们将进一步学习一种新的设计模式,装饰者模式
正文
装饰者模式的定义
装饰者模式可以动态地给某个对象添加一些额外的职责,而不会影响从这个类派生的其他类。比如说,你去买炸串,你想吃辣一点的,老板就给你的炸串多放了点辣椒粉,但是给你的那部分炸串放辣椒粉并不会影响到其他的炸串,也并不会因为老板给你炸串放多了点辣椒粉,你吃的就不是炸串了,它还是炸串,只不过是辣点的炸串。
在这个场景中,辣椒粉就是装饰者,而给炸串放辣椒粉让它比别的炸串更辣但是不影响它炸串本身性质的过程就是装饰者模式
装饰者模式的实现
和之前一样,在实现装饰者模式之前,我们先引入一个业务场景来方便大家理解,我们大家应该玩过飞机大战的小游戏,随着等级的提升,我们的飞机也会发出不一样的子弹,假设平时,我们发射的就是小子弹,等我们第一次升级的时候,就可以发射导弹,第二次升级的时候,就可以解锁激光炮,这里我们尝试用装饰者模式对这个场景实现一下,首先我们先实现一下最基本的飞机类型
然后我们需要再实现两个装饰类型去让飞机类型可以发射处导弹和激光炮
我们可以发现使用导弹和激光炮的装饰类型,并不会影响到飞机类本身的操作,飞机类本身还是会发射子弹,装饰类只是额外给了被装饰者对象本身不具备的能力而不会影响到它已经有的能力,就像开篇说的炸火腿肠多加点辣椒粉,并不会因为多加了辣椒粉,炸火腿肠的味道就不是火腿肠的味道了,只是额外赋予了一种辣的味道
基于javascript的装饰者模式实现
在刚学习设计模式的时候,我们就介绍到javascript是一种基于原型的语言,上一小结我们按照类型来定义,对于javascript而言其实是不必要的,我们可以直接通过修改对象或者给对象增加方法来实现,并不需要借助“类”来实现装饰者模式
在javascript中,函数作为一类对象,我们可以很轻松地给函数对象本身扩展一些功能,像上面这样实现,但是不可避免地会污染到原函数本身,这样其实是不符合开放-封闭原则的
用AOP装饰函数
在职责链的部分我们在Function的原型上实现了after方法,实际上我们只要实现before和after方法,然后把装饰者的方法传进去就可以实现装饰者模式
利用我们之前定义的方法就可以比较轻松地实现装饰者模式了
但是这样其实还有一个小问题,会污染Function的原型方法,所以考虑到这一点,我们可以把before和after提取出来单独做一个方法,下面以before为例:
小结
这一章我们学习了装饰者模式,装饰者模式在js中是很好实现的一种设计模式,但是如果直接在函数中进行扩展,会对原函数造成污染,不符合开放-封闭原则,所以我们介绍了怎么利用AOP去实现装饰者模式,因为AOP本身就是以装饰者模式为远离的编程思想,所以可以比较好地实现它