小议javascript设计模式(5)

作者:oldfish 来源:alipay UED 时间:2009-10-09 13:31:00 

Javascript设计模式之装饰者模式

装饰者模式:可以不创建新的子类,给对象创建新的功能。举例说明:支付宝收银台红包结合余额付款的应用场景。

var Ieconomics = new Interface("ieconomics",[["getPrice"]]);

首先创建一个组件类,基与该组件实例化的对象,会被作为参数传递给装饰者类,以便装饰者调用到该组件中的各方法。

  var economic = function(){ 
     Interface.regImplement(this,Ieconomics); 
   }; 
    economic.prototype={ 
        getPrice:function(){ 
          //代码实现 
        } 
    };

然后创建一个装饰者抽象类,作为派生装饰者选件类的父类:  

var economicsDecorator = function(economic){ 
      this.economic = economic; 
      this.regImplement(economic,Ieconomics); 
   }; 
    economicsDecorator.prototype={ 
        getPrice:function(){ 
          return this.economic.getPrice(); 
        } 
    };

最后基于上面这个抽象类,派生出一个装饰者选件类:

//红包装饰者选件类 
   var coupon = function(economic){ 
      //调用装饰着抽象类的构造函数 
      economicsDecorator.call(this,economic); 
   }; 
   extend(coupon,couponDecorator); 
   coupon.prototype=function(){ 
       //改写getPrice方法 
       getPrice:function(){ 
         return this.economic.getPrice() - this.getCoupon(); 
       }, 
       getCoupon:function(){ 
         //获取红包总价具体实现       
       } 
   };

var myCoupon = new economic(); 
    myCoupon = new coupon(myCoupon);

实现装饰者模式就是这么简单,首先创建一个组件的实例myCoupon,然后将该对象作为参数传递给装饰者选件类coupon。你会发现两句代码中我都把值赋给了变量myCoupon,这是因为他们都实现了同一个接口类,他们之间是可以互换使用的。

看到这里心细的同学可能会发现,我们在coupon类中新增了一个getCoupon方法,目前来看不会有任何问题,但是如果我们继续创建一个购物卷装饰者选件类,然后结合红包一起用呢?

//购物卷装饰者选件类 
   var voucher = function(economic){ 
     economicsDecorator.call(this,economic); 
   }; 
   extend(voucher,couponDecorator); 
   voucher.prototype=function(){ 
       getPrice:function(){ 
         return this.getPrice() - this.getVoucher(); 
       }, 
       getVoucher:function(){ 
         //获取优惠卷总价具体实现       
       } 
   };

var myCoupon = new economic(); 
    myCoupon = new coupon(myCoupon); 
    myCoupon = new voucher(myCoupon);

在这种场景下面getCoupon方法已经找不到了,这是因为voucher装饰myCoupon的时候,它的父类economicsDecorator不包含getCoupon方法,那自然是取不到的了,那该怎么办呢?

分析一下装饰者抽象类economicsDecorator,我们传递了一个myCoupon的引用作为参数,我们可以通过这个参数做一些小动作,获得新增加的方法。

var economicsDecorator = function(economic){ 
      this.economic = economic; 
      this.interface = Ieconomics; 
      for(var k in this.economic){ 
       if(typeof this.economic[key] !== "function"){ 
        continue; 
        var i; 
        for(i = 0;len = this.interface.methods.length,i < len; i++) { 
            //通过遍历比较在接口类中是否包含此方法,如果包含返回下一个 
            if(key == this.interface.methods[i][0]) {  
                break; 
            } 
        } 
        if(i < this.interface.methods.length) 
         continue; 
         var decorator = this; 
         //采用匿名函数调用方式来定义新方法 
         (function(methodName) { 
            decorator[methodName] = function() { 
                return decorator.economic[methodName](); 
            }; 
         })(key); 
        } 
       }  
      } 
      this.regImplement(economic,Ieconomics); 
   }; 
   economicsDecorator.prototype={ 
        getPrice:function(){ 
          return this.economic.getPrice(); 
        } 
    };

看上面的代码,我们对装饰者抽象类做了一些修改,这样做是为了确保在装饰者选件类中一旦定义新方法,可以在装饰者抽象类中动态的定义出来。这里只是提供一个使用装饰者模式的思路,具体的实现代码远比这个复杂,由于项目还在开发中,demo暂不提供,支付宝新版收银台发布后,会跟大家再做个详细的设计分享。

标签:设计模式,JavaScript,接口,组合模式
0
投稿

猜你喜欢

  • Python如何将给定字符串中的大写英文字母按以下对应规则替换

    2021-04-23 13:47:48
  • Python+drawpad实现CPU监控小程序

    2022-05-30 19:54:38
  • Oracle 9i轻松取得建表和索引的DDL语句

    2010-07-16 13:09:00
  • SQLServer2005 没有服务器名称的两种解决方法

    2024-01-20 10:29:43
  • SQL_Server全文索引的用法解析

    2024-01-17 08:37:14
  • 推荐4个原生javascript常用的函数

    2024-02-23 09:05:41
  • python logging设置level失败的解决方法

    2022-03-23 13:54:40
  • Javascript简写条件语句(推荐)

    2023-09-01 04:10:25
  • python 字符串格式化的示例

    2021-01-23 23:33:06
  • Python实现的检测网站挂马程序

    2023-11-21 16:39:38
  • Tensorflow 多线程与多进程数据加载实例

    2023-12-30 23:53:47
  • Python常见库matplotlib学习笔记之多个子图绘图

    2023-02-17 19:40:14
  • 使用Python脚本对GiteePages进行一键部署的使用说明

    2023-05-03 05:41:02
  • Python调用SQLPlus来操作和解析Oracle数据库的方法

    2024-01-27 19:17:06
  • Python如何使用字符打印照片

    2023-06-12 09:20:34
  • 基于Django框架的rest_framework的身份验证和权限解析

    2021-02-21 23:42:58
  • python数据结构之图的实现方法

    2022-12-29 04:59:38
  • 使用Python的Flask框架实现视频的流媒体传输

    2023-05-07 02:46:53
  • 如何避免查询调查结果时出现不相关主题的重复记录?

    2009-11-07 18:42:00
  • python打包多类型文件的操作方法

    2023-05-22 07:23:31
  • asp之家 网络编程 m.aspxhome.com