zoukankan      html  css  js  c++  java
  • js设计模式

    什么是装饰者模式

    装饰者模式可以动态地给一个对象添加一些额外的职责。就增加功能来说,装饰者模式比通过继承生成子类更为灵活。

    下面通过一个例子来详细的介绍一下。

    我们销售一台电脑,每个电脑都是一个新的Computer对象,它都有一个price属性来表示价格,并且可以通过它的getPrice方法来得到它的价格:

    var Computer = function(price){
      this.price = price || 100;
    };
    
    Computer.prototype.getPrice = function(){
      return this.price;
    };

    现在有个客户想要再加个内存条,如果通过继承的方式,我们要新增一个ComputerWithMemory对象。

    var ComputerWithMemory = function(price){
      Computer.constructor.call(this, price);
    };
    ComputerWithMemory.prototype = new Computer();
    ComputerWithMemory.prototype.getPrice = function(){
      return this.price + 20;
    };

    我们来验证一下:

    var computer = new Computer();
    var computer1 = new ComputerWithMemory();
    
    computer.getPrice();  // 100
    computer1.getPrice();  // 120

    如果客户要加个固态硬盘,我们就有要再新增一个ComputerWithSSD对象,如果客户既要内存条,又要固态硬盘,那我们就要再新增一个ComputerWithMemoryAndSSD对象。

    下面我们来用装饰者模式实现:

    我们在Computer中加一个_decorateList属性来保存添加到对象上的装饰者列表:

    var Computer = function(price){
      this.price = price || 100;
      
      this._decoratorList = [];
    };

    接下来,我们在Computer对象上预先定义好需要的装饰者:

    Computer.decorators = {};
    Computer.decorators.memory = {
      getPrice : function(price){
        return price + 20;
      }
    };

    Computer.decorators用来存储我们的装饰者。上面我们定义了一个加内存条的装饰者memory,注意它的getPrice方法是带参数price的。

    到这里装饰者我们已经有了,但是装饰者是需要注册到具体对象上去的,我们就需要在加一个注册的方法:

    Computer.prototype.decorate = function(decorate){
      this._decoratorList.push(decorate);
    };

    注册方法很简单,就是把要注册的装饰者加入到对象的装饰者列表中。参数decorate表示装饰者的名字,例如如果是上面的memory装饰者,参数decorate就是字符串“memory”。

    最后我们再重写一下getPrice方法:

    Computer.prototype.getPrice = function(){
      // 先得到我们的原价  
      var price = this.price;
      // 遍历注册了的装饰者
      for(var i = 0, len = this._decoratorList.length; i < len; i++){
        var name = this._decoratorList[i];
        // 根据装饰者的名字得到装饰者
        // 再调用装饰者的getPrice方法来处理我们的价格price
        price = Computer.decorators[name].getPrice(price);
      }
      
      return price;
    };

    这样我们的装饰者模式就完成了,我们再来测试一下:

    var computer = new Computer();
    computer.getPrice();    // 100
    
    // 加个内存条
    computer.decorate('memory');
    computer.getPrice();    // 120

    现在如果我们要想加一个固态硬盘,我们只要在Computer对象上再加个ssd装饰者:

    Computer.decorators.ssd = {
      getPrice : function(price){
        return price + 30;
      }
    };

    再来测试一下:

    var computer = new Computer();
    
    // 加个固态硬盘
    computer.decorate('ssd');
    computer.getPrice();    // 130
    
    // 再加个内存条
    computer.decorate('memory');
    computer.getPrice();    // 150
  • 相关阅读:
    2018/03/27 每日一个Linux命令 之 cron
    2018/03/26 每日一个Linux命令 之 du
    《Nginx
    学习计划 mysql explain执行计划任务详解
    方法覆盖
    二维数组中的查找
    oracle导入少量数据(少于10M)
    hive计算日期差
    查看文件编码格式以及更改编码
    java io流
  • 原文地址:https://www.cnblogs.com/lbin/p/5016908.html
Copyright © 2011-2022 走看看