JS设计模式五:装饰者模式
装饰者模式的定义:
装饰者(decorator)模式能够在不改变对象自身的基础上,在程序运行期间给对像动态的添加职责。与继承相比,装饰者是一种更轻便灵活的做法。
装饰者模式的特点:
可以动态的给某个对象添加额外的职责,而不会影响从这个类中派生的其它对象;
---------------继承的一些缺点:
继承会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之改变;
超类的内部细节对于子类是可见的,继承常常被认为破坏了封装性;
总结
装饰者模式是为已有功能动态地添加更多功能的一种方式,把每个要装饰的功能放在单独的函数里,然后用该函数包装所要装饰的已有函数对象,因此,当需要执行特殊行为的时候,调用代码就可以根据需要有选择地、按顺序地使用装饰功能来包装对象。优点是把类(函数)的核心职责和装饰功能区分开了。
举个栗子
//装饰者模式
function Sale(price){
this.price = price || 100;
}
Sale.prototype.getPrice = function(){
return this.price;
}
Sale.prototype.decorate = function(decorator){
//临时构造函数,继承当前对象,装饰新对象
var F = function(){},
overrides = this.constructor.decorators[decorator],
i,newobj;
F.prototype = this;
newobj = new F();
//父类引用相当于__proto__
newobj.father = F.prototype;
for(i in overrides){
if(overrides.hasOwnProperty(i)){
newobj[i] = overrides[i];
}
}
return newobj;
}
Sale.decorators = {};
Sale.decorators.fedtax = {
getPrice:function(){
var price = this.father.getPrice();
price += price * 5 / 100;
return price;
}
};
Sale.decorators.quebec = {
getPrice:function(){
var price = this.father.getPrice();
price += price * 7.5 / 100;
return price;
}
}
Sale.decorators.money = {
getPrice:function(){
return "$" + this.father.getPrice().toFixed(2);
}
}
Sale.decorators.cdn = {
getPrice:function(){
return "CDN$" + this.father.getPrice().toFixed(2);
}
}
//测试
var sale1 = new Sale(100);
console.log(sale1);
sale2 = sale1.decorate('fedtax');
console.log(sale2);
sale3 = sale2.decorate('quebec');
console.log(sale3);
sale4 = sale3.decorate('money');
console.log(sale4);
// console.log(sale.getPrice()); //结果 $112.88
// sale = new Sale(100);
// sale = sale.decorate('fedtax');
// sale = sale.decorate('cdn');
// console.log(sale.getPrice()); //结果 CDN$ 105.00