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

posted @ 2017-03-30 14:59  a fine day  阅读(84)  评论(0编辑  收藏  举报