装饰者模式就是透明把对象包装在具有同样接口的另一对象中。相对于创建子类来说,装饰者是一种友好的选择。
装饰者用于给对象增加功能,可以创造大量的子类。
例如:
function extend(subClass, superClass){
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
}
//组建类 基类
function Bicycle(){}
Bicycle.prototype = {
assemble:function(){
return "一辆车";
},
wash:function(){},
ride:function(){},
repair:function(){},
getPrice:function(){
return 399.0;
}
};
//装饰者类 实现与组建类同样的接口
var BicycleDecorator = function(bicycle){
this.bicycle = bicycle;
}
BicycleDecorator.prototype = {
assemble:function(){
return this.bicycle.assemble();
},
wash:function(){
return this.bicycle.wash();
},
ride:function(){
return this.bicycle.ride();
},
repair:function(){
return this.bicycle.repair();
},
getPrice:function(){
return this.bicycle.getPrice();
}
};
//我们需要有两车灯的自行车
var HeadlightBicycle = function(bicycle){
HeadlightBicycle.superclass.constructor.call(this, bicycle);
}
extend(HeadlightBicycle, BicycleDecorator);
HeadlightBicycle.prototype.assemble = function(){
return this.bicycle.assemble() + '两个车灯';
}
HeadlightBicycle.prototype.getPrice = function(){
return this.bicycle.getPrice() + 99;
}
//我们需要有一个铃铛的自行车
var BasketBicycle = function(bicycle){
BasketBicycle.superclass.constructor.call(this, bicycle);
}
extend(BasketBicycle, BicycleDecorator);
BasketBicycle.prototype.assemble = function(){
return this.bicycle.assemble() + '一个铃铛';
}
BasketBicycle.prototype.getPrice = function(){
return this.bicycle.getPrice() + 200;
}
//拥有两个车灯的自行车
var bicycle = new Bicycle();
alert(bicycle.getPrice());
var myBicycle1 = new HeadlightBicycle(bicycle);
alert(myBicycle1.assemble());
alert(myBicycle1.getPrice());
//在两个车灯的前提下,增加一个铃铛
var myBicycle2 = new BasketBicycle(myBicycle1);
alert(myBicycle2.assemble());
alert(myBicycle2.getPrice());
我们可以动态的应用装饰者,创造出具有特性的对象。
装饰者接口的角色:
1、说明装饰者必须实现的方法。
2、装饰者对象与组建能够互换使用。
装饰者模式与组合模式的比较:
1、都是用来包装对象,在组合模式中称之为子对象,装饰者模式中称之为组件。
2、组合模式是一种结构模式,用于将众多子对象组织为一个整体,将大批对象当作一个整体对象处理,作为一个组织层次结构的树,不会修改方法的调用,而是将组合对象沿着子对象链向下传递,最终落在叶对象中。
3、装饰者模式是结构型模式,不是用于组织对象,而是在不修改现有对象的前提下为其增加新的职责。目的是用于对方法的修改。组合对象不修改方法调用,目的是在于子对象。然而装饰者是修改方法,子对象只能有一个。
装饰者修改组建的方式
1、方法之后添加行为
先调用组件的方法,然后在实施附加的方法。
2、在方法之前添加行为
修改行为放生在执行组件之前。
3、替换方法
对方法进行整体替换,组件的方法将不会被调用。需注意的是这个装饰者的顺序至少要放到其余同样方法后应用。
4、添加新方法
工厂模式适合创建装饰对像。
函数装饰者
function upperCaseDecorator(func){
return function(){
return func.apply(this,arguments).toUpperCase();
}
}
function getDate(){
return (new Date()).toString();
}
getDateCaps = upperCaseDecorator(getDate);
alert(getDate());
alert(getDateCaps());
这样 upperCaseDecorator也是对getDate函数的装饰
适用场合
为类添加特性与职责,如果派生子类不实际的话,就要用到装饰者模式。
为对象添加特性,而不想修改对象,用到装饰者模式。