????? 委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin。
“委托”在C#中是一个语言级特性,而在Java语言中没有直接的对应,但是我们可以通过动态代理来实现委托!代码如下:
- import?java.lang.reflect.InvocationHandler; ??
- import?java.lang.reflect.Method; ??
- import?java.lang.reflect.Proxy; ??
- /* ?
- ?*?@author?Liusheng ?
- ?*?实现“委托”模式,用户需要实现InvocationHandler接口; ?
- ?*?参考:http://www.uml.org.cn/j2ee/200411036.htm ?
- ?*/??
- public?abstract?class?Delegator?implements?InvocationHandler?{ ??
- ????//RelegateTo针对每个对象都要生成一个实例,因而非Static的log,代价比较高。 ??
- ????//protected?Log?_log?=?LogFactory.getLog(this.getClass());?? ??
- ????//private?static?Log?_log?=?LogFactory.getLog(RelegateTo.class); ??
- ????//-------------------------------------------- ??
- ????protected?Object?obj_orgin?=?null;??//原始对象 ??
- ????protected?Object?obj_proxy?=?null;??//代理对象 ??
- ????//-------------------------------------------- ??
- ????public?Delegator()??{ ??
- ????????//空 ??
- ????} ??
- ????public?Delegator(Object?orgin){ ??
- ????????this.createProxy(orgin); ??
- ????} ??
- ????//-------------------------------------------- ??
- ????protected?Object?createProxy(Object?orgin)?{ ??
- ????????obj_orgin?=?orgin; ??
- ????????obj_proxy?=?Proxy.newProxyInstance( ??
- ????????????????orgin.getClass().getClassLoader(),??//加载器 ??
- ????????????????orgin.getClass().getInterfaces(),???//接口集 ??
- ????????????????this);??//委托 ??
- ????????//_log.debug("#?委托代理:"+obj_proxy); ??
- ????????return?obj_proxy; ??
- ????}??? ??
- ????protected?Object?invokeSuper(Method?method,?Object[]?args) ??
- ????throws?Throwable?{ ??
- ????????return?method.invoke(obj_orgin,?args);?? ??
- ????} ??
- ????//--------------实现InvocationHandler接口,要求覆盖------------ ??
- ????public?Object?invoke(Object?obj,?Method?method,?Object[]?args) ??
- ????throws?Throwable?{ ??
- ????????//?缺省实现:委托给obj_orgin完成对应的操作 ??
- ????????if?(method.getName().equals("toString"))?{??//对其做额外处理 ??
- ????????????return?this.invokeSuper(method,?args)+"$Proxy"; ??
- ????????}else?{?????//注意,调用原始对象的方法,而不是代理的(obj==obj_proxy) ??
- ????????????return?this.invokeSuper(method,?args); ??
- ????????} ??
- ????} ??
- }??
下面的代码,则是作为一个委托的例子,实现Map的功能。
- import?java.io.IOException; ??
- import?java.lang.reflect.Method; ??
- import?java.util.Hashtable; ??
- import?java.util.Map; ??
- import?org.apache.commons.logging.Log; ??
- import?org.apache.commons.logging.LogFactory; ??
- import?com.bs2.core.UtilLog; ??
- /** ?
- ?*?@author?Liusheng ?
- ?*?本代码主要用于演示RelegateTo的使用方法 ?
- ?*/??
- public?class?Delegator4Map?extends?Delegator?{ ??
- ????private?static?Log?_log?=?LogFactory.getLog(Delegator4Map.class); ??
- ????private?Map?orginClass?=?null;??//原始对象 ??
- ????private?Map?proxyClass?=?null;??//代理对象 ??
- ???? ??
- ????public?Map?getOrgin()?{?return?orginClass;??} ??
- ????public?Map?getProxy()?{?return?proxyClass;??} ??
- ???? ??
- ????public?Delegator4Map(Map?orgin)?{ ??
- ????????super(orgin); ??
- ????????orginClass?=?orgin; ??
- ????????proxyClass?=?(Map)super.obj_proxy; ??
- ????} ??
- ????public?Object?invoke(Object?obj,?Method?method,?Object[]?args) ??
- ????throws?Throwable?{ ??
- ????????if?(method.getName().equals("size"))?{??//修改close处理逻辑 ??
- ????????????_log.debug("原始?size()="+super.invoke(obj,?method,?args)); ??
- ????????????Object?res2?=?new?Integer(-1); ??
- ????????????_log.debug("修改?size()="+res2); ??
- ????????????return?res2; ??
- ????????}else?{ ??
- ????????????return?super.invoke(obj,?method,?args); ??
- ????????} ??
- ????}??? ??
- ????public?static?void?main(String[]?args)?throws?IOException?{ ??
- ????????UtilLog.configureClassPath("resources/log4j.properties",?false); ??
- ????????Delegator4Map?rtm?=?new?Delegator4Map(new?Hashtable()); ??
- ????????Map?m?=?rtm.getProxy(); ??
- ????????m.size(); ??
- ????????_log.debug("代理:"+m.toString()); ??
- ????} ??
- }??
注意:UtilLog仅仅是用于配置log4j属性文件位置,如果log4j.properties就在缺省的运行路径下,则无需单独配置。或者用System.out输出来替代_log输出。