我所理解的装饰者模式,在不破坏原有函数或方法的内部结构下,并能增强原有函数或方法!
js作为解释执行的语言,动态的改变对象的方法来新增功能是比较常见的,比如
var obj = {
name:'gaofeng',
address:"广州市"
}
obj.address = obj.address +"天河区"
console.log(obj.address) //广州市天河区
上面就是我们最原始的增强对象方法的功能的操作
假如说我们用js的构造函数来实现的话
var Plane = function(){}
Plane.prototype.fire = function(){
console.log('发射普通子弹')
}
var MissleDecorator = function(plane){
this.plane = plane
}
MissleDecorator.prototype.fire = function(){
this.plane.fire()
console.log("发射导弹")
}
var AtomDecorator = function(plane){
this.plane = plane
}
AtomDecorator.prototype.fire = function(){
this.plane.fire()
console.log("发射原子弹")
}
var plane = new Plane()
plane = new MissleDecorator(plane)
plane = new AtomDecorator(plane)
plane.fire()
//发射普通子弹
//发射导弹
//发射原子弹
基本思想就是把对象的实例作为参数传入我们的新的增强方法里面,新的类有和需要装饰的类相同的方法(fire),因此我们在调用的时候看不出任何的不舒适,所有的增强功能都执行了,初始类的方法也执行了!
在javascript的世界里,一切皆object!那么我们用对象的思想如何实现上面的装饰思想呢
var plane = {
fire(){
console.log('发射普通子弹')
}
}
var missleDecorator = function(){
console.log('发射导弹')
}
var atomDecorator = function(){
console.log('发射导弹')
}
var fire1 = plane.fire
plane.fire = function(){
fire1()
missleDecorator()
}
var fire2 = plane.fire
plane.fire = function(){
fire2()
atomDecorator()
}
plane.fire()
通过引用赋值,保存之前的功能,然后在此基础上新增功能
下面是反例
var test = function(){
console.log(1)
}
var test = function(){
console.log(1)
console.log(2)
}
这种思路破坏之前的原方法,不符合开放-封闭原则,即对拓展开发,对修改禁止的原则
下面是正例
var a = function(){
console.log(1)
}
var _a = a
a = function(){
_a()
console.log(2)
}
下面是拓展的两种方法
Function.prototype.before = function(beforeFn){
var _self = this
/* console.log(this,'_this') */
return function(){
beforeFn.apply(null,arguments)
/* console.log(this,'neibu') */
return _self.apply(null,arguments)
}
}
var a = function(d){
console.log(d,'我是a')
}
var c = function(d){
console.log(d,'我是c')
}
var b = c.before(a)
b('哈哈,这是一个高级用法a')
Function.prototype.after = function(afterFn){
var _self = this
return function(){
var ret = _self.apply(this,arguments)
afterFn.apply(this,arguments)
return ret
}
}
var e = function(e){
console.log(e,'我是e')
}
var f = function(f){
console.log(f,'我是f')
return '我是f'
}
var g = f.after(e)
const q = g('after')
console.log(q)
大概的知识点就是这些!下面会再完善一些实例的使用吧!