你能用Wapper来做什么?

从简单的说起:
一、在只有值传递的语言中,通过Wapper把实参Wapper之后,实现副作用:
在工具箱里写上我们要用的Wrapper:

Java代码  复制代码
  1. public class Wrapper<T extends Object> {  
  2.     public T object;  
  3.   
  4.     public Wrapper() {  
  5.         object = null;  
  6.     };  
  7.   
  8.     public Wrapper(T object) {  
  9.         this.object = object;  
  10.     }  
  11. }  

 下面我们看看一个从内部类获得副作用的例子:
由于内部类使用外部变量必须是final的,这样试图使用一个变量直接得到
内部类操作的结果不能够实现,这时候我们的Wrapper派上了用场:

Java代码  复制代码
  1. final Wrapper<String> wrapper = new Wrapper<String>();  
  2. Display.getDefault().syncExec(new Runnable() {  
  3.     public void run() {  
  4.        wrapper.object = ....;  
  5.     }  
  6. }  

 我们可以成功的从一个内部类中获得我们需要的数据。


下面我们看一个经典的swap函数:

Java代码  复制代码
  1. void swap(int a,int b){  
  2.    int temp = a;  
  3.    a = b;  
  4.    b = temp;  
  5. }  

 这个简单的swap函数不起作用的,而java等语言参数传递只支持值传递,
所以不管是参数是基本类型还是Object类型,都不能写出可以swap两个值的函数。
如果我们非得想有这么一个swap函数来交换两个值,那该怎么办?这时候wapper又派上用场了。
在我们的工具箱找到Wrapper:
写我们的交换函数:

Java代码  复制代码
  1. void swap(Object a,Object b){  
  2.    Object temp = a.value;  
  3.    a.value = b.value;  
  4.    b.value = temp;  
  5. }  
  6. String a = "abc";  
  7. String b = "bcd";  
  8. Wrapper<String> wrapperA = new Wrapper<String>(a);  
  9. Wrapper<String> wrapperB = new Wrapper<String>(b);  
  10. swap(wrapperA,wrapperB);  

 在用javascript写XPCOM的时候,数组及其大小作为返回值(由于idl与实现语言无关,
需要返回数组的大小),两个返回值,javascript是不支持的,并且在javascript
只有值传递的语言,使用参数直接作为返回值是不能实现的,这时候Wapper就派上了
用场:

Java代码  复制代码
  1. idl:  
  2. void getArray(out unsigned long count,[retval, array, size_is(count)] out string aArray);  

 js实现:

 

Js代码  复制代码
  1. getArray: function(aCount){  
  2.   aCount.value = this.aArray.length;  
  3.   return this.aArray;  
  4. };  

 

使用方法:

Js代码  复制代码
  1. var aCount = {};一个Wapper  
  2. var array = xx.getArray(aCount);  
  3. xxx.alert(aCount.length);  

  二、控制实例产生的个数/生命周期:
最常见的一个Wrapper要算单例模式了:

Java代码  复制代码
  1. public class Singleton{  
  2.     private static Singleton instance = new Singleton();  
  3.     private Singleton(){  
  4.     }  
  5.   
  6.     public static Singleton getInstance(){  
  7.         return instance;  
  8.     }  
  9. }  

 这个Wrapper或许有点特别,自己Wrapper自己,来控制实例产生的个数/生命周期。
上次写了一个获取Post数据的firefox插件,XPCOM nsPostDataManager最早使用:

Js代码  复制代码
  1. var catman = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);  
  2.           
  3.         catman.addCategoryEntry("JavaScript global property",  
  4.                     CLASS_NAME,  
  5.                     CONTRACT_ID,  
  6.                     true,   
  7.                     true);  

 来注册。
这样可以在网页全局访问getPostData和clearRequests接口方法。但是结果去每次都为空,跟踪发现
每打开一个新的Tab页,nsPostDataManager就会有一个新的实例生成,从而使得收集post请求的实例,
和在页面要使用的实例不是一个。这时候Wrapper又可以出头露面了,再写一个Wrapper组件nsPostDataService::

Js代码  复制代码
  1. getPostData: function(aCount){  
  2.     //在XPCOM中getService每次使用一个实例,而createInstance每次创建一个实例  
  3.     var nsPostDataManager = Cc["@ibm.com/nspostdatamanager;1"].getService(Ci.nsIPostDataManager);  
  4.     return nsPostDataManager.getPostData(aCount);  
  5. },  
  6.       
  7. clearRequests: function(){  
  8.     var nsPostDataManager = Cc["@ibm.com/nspostdatamanager;1"].getService(Ci.nsIPostDataManager);  
  9.     return nsPostDataManager.clearRequests();  
  10. }  

 这时候把nsPostDataService注册成网页全局访问的就可以了。

三、控制对象的访问:
Proxy模式其实也是一个Wrapper,通过Wrapper这个对象来控制对象的访问,并转发消息到实际对象。
四、为对象动态增加行为:
Proxy模式的动态代理可以实现AOP,为对象动态增加行为。Spring的AOP就是使用了Java动态代理。
装饰模式可以动态的Wrapper对象,来为对象增加行为:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

Extension Object模式则可以为Object动态添加新的行为而不改变已有的接口,然后Query到需要的接口,使用新行为。
Wrapper还有很多使用的场合,希望大家补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值