直接转帖ajoo的大作
内容节选如下:
?Map
<String, String>
非常非常复杂深奥。
好,现在我们事先知道要从这个map
里读取一些数据点,比如:id
, name
, sex等等。
对id
,我们知道读出来的是int;对name
,是string;对sex,应该对应一个叫Gender的enum类型。
这就涉及一个自动类型转换的问题。我们希望不用对每个数据点做手工类型转换。
另外一个需求,一些数据点是有缺省值的。比如name
我们可以缺省为空字符串。
这样,如果map
里面没有某个值,我们就看缺省值,如果有,就用这个缺省值,如果没有,就抛异常。
手工做的话,大概是这样:
String id
Value = map
.get("id
"); if (id
Value == null) { throw ...; } int id
= Integer.parseInt(id
Value); String name
= map
.get("name
"); if (name
== null) { name
= ""; } String sexValue = map
.get("sex"); if (sexValue == null) { throw ...; } Gender sex = Gender.valueOf(sexValue); ...
比较痛苦。于是做了一个动态代理
:
public final class PropertyConverter<T> { private final Class<T> targetType; private PropertyConverter(Class<T> targetType) {...} public static <T> PropertyConverter<T> to(Class<T> targetType) { return new PropertyConverter<T>(targetType); } public T from(final Map
<String, String> map
) { return Proxy.newProxyInstance( new Class[]{targetType}, targetType.getClassLoader(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) { String value = map
.get(method.getName
()); if (value == null) { Object defaultValue = method.getDefaultValue(); if (defaultValue == null) { throw ...; } return defaultValue; } return convert(value, method.getReturnType()); } }); } }
convert()函数是调用apache的ConvertUtilsBean做的,没什么说的。
那么,用法呢? @interface Foo { int id
(); String name
() default ""; Gender sex(); } Map
<String, String> map
= ...; Foo foo = PropertyConverter.to(Foo.class).from(map
); foo.id
(); foo.name
();
这里面,对annotation的用法比较特别。不过不这么做,java也不提供一个简单并且类型安全的指定缺省值的方法。当然,如果你凑巧不需要缺省值,那么也不用annotation,直接用interface就好。
动态代理(或者静态代理模式)在处理通用过程方面确实是非常常见的解决方案。 做了这么久的开发,作为一个中级程序员,看到很繁琐累赘的代码四散在项目里时,我们就应该考虑设计模式了。 不同于软件界面的改进,虽然老板看不见(/看不懂)产品内在的进化和我们冥思苦想的技术结晶,但它可以让我们活得更轻松,做得更好,更加游刃有余。 谨以此同勉!
? 【2008-6 bbs】
?
我们目前用到的spring的事务管理模块,buffalo,都是采用的动态代理技术。
因为良好的设计,往往可以减少大量的代码量和工作时间,使项目结构清晰易读,容易重构升级,并减少bug!
我一直自认是个”懒“人,也觉得每个程序员都应该变得更”懒“,凡是可以让我们更快开发,更快测试,更快发布的技术/方案/思想都应该迅速学习和接收,自己也要能开发、积累趁手的工具来加xx率。
据说IBM有个统计,不同水平程序员之间的开发效率差距{zd0}可以达到恐怖的20倍!估计那都是日积月累之功,但如果个体不会思考,不想进步,那工作再久也是不能升华的。
后来我在项目应用了这个技巧,读取配置文件很方便,主要是有代码完成。缺点是如果增添配置文件的属性则需要增添接口的方法,这带来一点麻烦。