a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 123|回复: 0

[专业语言] Java认证辅导:关于用动态代理进行修饰(3)

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
清单 7 显示的动态代办代庖搜检被挪用体例的名称,并经由过程发芽或改削属性图直接实现 getter 和 setter 体例。此刻,章矣闽代办代庖类就能实现多个 JavaBean 气概接口的对象。
& F% |  F# J: d3 j清单 7. 用于把 getter 和 setter 分拨给 Map 的动态代办代庖类+ g% S5 v: r; q9 g( Y
public class JavaBeanProxyFactory { private static class JavaBeanProxy implements InvocationHandler { Map《String, Object》 properties = new HashMap《String, Object》(); public JavaBeanProxy(Map《String, Object》 properties) { this.properties.putAll(properties); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String meth = method.getName(); if (meth.startsWith(“get”)) { String prop = meth.substring(3); Object o = properties.get(prop); if (o != null && !method.getReturnType().isInstance(o)) throw new ClassCastException(o.getClass().getName() + “ is not a ” + method.getReturnType().getName()); return o; } else if (meth.startsWith(“set”)) { // Dispatch setters similarly } else if (meth.startsWith(“is”)) { // Alternate version of get for boolean properties } else { // Can dispatch non get/set/is methods as desired } } } public static《T》 T getProxy(Class《T》 intf, Map《String, Object》 values) { return (T) Proxy.newProxyInstance (JavaBeanProxyFactory.class.getClassLoader(), new Class[] { intf }, new JavaBeanProxy(values)); } }
( y/ _' x4 R; ]' P2 l虽然因为反射在 Object 上工作会有潜在的类型平安性上的损失踪,可是,JavaBeanProxyFactory 中的 getter 措置会进行一些需要的额外的类型检测,就像我在这里用 isInstance() 对 getter 进行的检测一样。
/ \# }, k. L, b+ J  z机能成本2 O) G' ~+ H  E9 u9 r3 h
正如已经看到的,动态代办代庖拥有简化大量代码的潜力 —— 不仅能替代良多生成的代码,而且一个代办代庖类还能庖代多个手写的类或生成的代码。什么是成本呢?因为反射地分拨体例而不是采用内置的虚体例分拨,可能有一些机能上的成本。在早期的 JDK 中,反射的机能很差(就像早期 JDK 中几乎其他每件事的机能一样),可是在近 10 年,反射已经变得快多了。/ Z. `% Z9 ?  b: ^& H1 Q
不必进入基准测试机关的主题,我编写了一个简单的、不太科学的测试轨范,它轮回地把数据填充到 Set,随机地对 Set进行插入、发芽和删除元素。我用三个 Set 实现运行它:一个未经润色的 HashSet,一个手写的、只是把所有体例转发到底层的 HashSet 的 Set 适配器,还有一个基于代办代庖的、也只是把所有体例转发到底层 HashSet 的 Set 适配器。每次轮回迭代都生成若干随机数,并执行一个或多个 Set 操作。手写的适配器比起原始的 HashSet 只发生很少百分比的机能负荷(概略是因为 JVM 级有用的内联缓冲和硬件级的分支展望);代办代庖适配器则较着比原始 HashSet 慢,可是开销要少于两个量级。  t) M5 L7 e" r2 O  L6 `0 o8 O
我从这个试验得出的结论是:对于大大都情形,代办代庖体例即使对轻量级体例也执行得足够好,而跟着被代办代庖的操作变得越来越重量级(例如远程体例挪用,或者使用序列化、执行 IO 或者从数据库检索数据的体例),代办代庖开销就涣有用地接近于 0。当然也存在一些代办代庖体例的机能开销无法接管的情形,可是这些凡是只是少数情形。
' H' Z. `2 u1 V8 g. \4 D/ i竣事语, B( x* O& ^! g; i& q8 s3 h! d
动态代办代庖是壮大而未充实操作的工具,可以用于实现良多设计模式,搜罗 Proxy、Decorator 和 Adapter。这些模式基于代办代庖的实现轻易编写,更难犯错,而且具备更好的通用性;在良多情形下,一个动态代办代庖类可以充任所有接口的 Decorator 或 Proxy,这样就不用每个接口都编写一个静态类。除了最关注机能的应用轨范之外,动态代办代庖体例可能比手写或机械生成 stub 的体例更可取。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-4-29 16:04 , Processed in 0.171737 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表