这里讲述的是一个非常让人尴尬的故事
我们有一个简单的java类:
class Details {
double getBalance();
double getFixed();
double getVariable();
double getSpendDown();
...
//各种getter以及其他相关的逻辑
}
现在业务逻辑需要对一些property做求和操作,求overallBalance, overallFixed之类的。
没什么了不起的,一个for循环分分钟搞定:
static double getOverallBalance(Details[] arr){
double sum = 0;
for(int i=0; i<arr.length; i++) {
sum += arr[i].getBalance();
}
}
同理,对overallFixed,代码大同小异,copy-paste先。
static double getOverallFixed(Details[] arr){
double sum = 0;
for(int i=0; i<arr.length; i++) {
sum += arr[i].getFixed();
}
}
这都没什么。可是当我写到第七个getOverallBlahBlah(arr)函数的时候,终于有点受不了了。这代码重复的虽然不多,但是架不住这么没完没了阿。
作为code-against-interface的推崇者,作为一个函数式编程的扇子,最自然的想法就是把不同的getter逻辑抽象成一个Getter接口,如下:
interface Getter {
double get(Details details);
}
static double sum(Details[] arr, Getter getter){
double sum = 0;
for(int i=0; i<arr.length; i++) {
sum += getter.get(arr[i]);
}
}
娜爱思啊。有比这代码更优雅的么?
然后各个求和的代码变成:
double overallBalance = sum(details, new Getter(){
public double get(Details details){
return details.getBalance();
}
});
double overallFixed = sum(details, new Getter(){
public double get(Details details){
return details.getFixed();
}
});
....
嗯。几乎没有什么重复的逻辑了。
不过......
数数代码行数,怎么没有减少,反而略有盈余?仔细找找。发现原来的for loop是四行,现在的new Getter(){...}居然也是四行!!!
再加上一个sum()函数,我辛苦了半天的重构,居然代码行数增加了!
如果世界上有比一个java的匿名类的语法更臭的,那大概就是两个匿名类语法了。据说居然还有人质疑java 7引入closure语法的意义?
另一个方法是用apache commons beanutils的getProperty(),最终的语法会是:
double overallBalance = sum(details, "balance");
语法足够简单了,但是重构的时候就麻烦了,也没有code-completion可用。
尴尬阿。这么一个简单的for loop,用匿名类重构似乎不值得。但是就任由这七个(也许回头还会更多)长得一模一样的for loop这么站在这气我?
走投无路,开始琢磨奇技淫巧了。
先声明一个接口,来包含所有需要sum的property getter。
private interface IDetails {
double getBalance();
double getFixed();
double getVariable();
double getSpendDown();
...
//所有其它需要做sum的getter
}
然后让Details实现IDetails。Details的代码不用变。
class Details implements IDetails {
...
//代码不变
}
戏肉来了。写一个dynamic proxy,来封装sum逻辑。
static IDetails sumOf(final IDetails[] arr){
return (IDetails)Proxy.newProxyInstance(
getClass().getClassLoader(), new Class[]{IDetails.class}, new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
double sum = 0;
for(int i=0; i<arr.length; i++) {
sum += ((Double)method.invoke(arr[i], args)).doubleValue();
}
return new Double(sum);
}
});
}
好了,接下来求sum的语法可以被简化为如下:
double overallBalance = sumOf(arr).getBalance();
double overallFixed = sumOf(arr).getFixed();
...
而且,再需要sum新的property,只需要把这个getter放进IDetails接口,就大功告成了。
很有趣的dynamic proxy应用。不过,一个求和这么简单的事情居然要动用这种奇技淫巧,很值得自豪么?
要是在ruby里,我就直接:
sum(arr){balance}
该死的java啊!
分享到:
相关推荐
Python 语言奇技淫巧总结 Python 语言作为一种高效、灵活的编程语言,具有许多奇技淫巧,可以帮助开发者提高编程效率和代码质量。在本文中,我们将探讨 Python 语言中的四大奇技淫巧:循环代码优化、异常处理,以及...
标题中提到的“来自小密圈里的那些奇技淫巧”可能是指在特定的技术圈子中分享的一些特殊技巧,用于突破安全限制和进行有效的攻击测试。以下将详细解释文档中提及的各个技巧: 1. EVAL长度限制突破技巧: 在PHP中,`...
Python,作为一门广受欢迎的编程语言,在...总之,Python的这些“奇技淫巧”展示了这门语言在实际编程中灵活多变的应用能力,对于学习和使用Python的开发者而言,了解这些技巧能够极大地提高开发效率和程序的用户体验。
《算法心得-高效算法的奥秘(原书第2版)》是一本深入探讨算法精髓的书籍,...书中的"位运算的奇技淫巧"部分,无疑是将这种技术运用到极致的探索,对于有志于提升算法水平的开发者来说,是一份不可多得的参考资料。
vue有哪些奇技淫巧
JavaScript是世界上最流行的编程语言之一,尤其在Web开发领域中占据着核心地位。它不仅可以用于创建交互式的网页,还可以用于移动应用开发、服务器端编程...在JavaScript的世界里,还有很多其他的奇技淫巧等待探索。
【DNS基础及安全应用】 DNS(Domain Name System)是互联网中的关键组件,负责将人类可读的域名转换为网络可以理解的IP地址。其工作原理是通过查询和响应机制,确保用户能正确访问网络资源。当用户输入一个域名时,...
RocketMQ 奇技淫巧之 ServiceLoader 源码解读 抓下来打包成了HTML文件, 方便离线观看
开源电子书《JavaScript奇技淫巧》,『奇技淫巧』一词出自古籍《书·泰誓下》,指新奇的技艺和作品。此词意与本书内容十分契合,因此书名借用该词。
在这个“Go-Git的奇技淫巧”中,我们将探讨一些高级和实用的Git技巧,以及如何使用Go来进一步操作Git。 1. **分支管理**:Git的分支机制允许开发者在同一项目上并行工作。`git branch`命令用于创建、查看和切换分支...
Java 8 中 Stream API 的奇技淫巧 Java 8 中的 Stream API 是一种功能强大且实用的数据处理工具,能够帮助开发者更高效地处理数据。Stream API 的出现是为了解决 Java 中处理数据的痛点,提供了一种简洁、灵活、...
Git的奇技淫巧在软件开发领域中是一个广泛讨论的话题,因为它的功能强大且灵活性极高。Git不仅仅是一个“分布式版本管理工具”,它还是一个能够帮助开发者跟踪代码变化、协同工作和回溯错误的强大系统。在JavaScript...
C语言中的奇技淫巧 C语言是一门功能强大且灵活的编程语言,学习C语言的过程中,总会遇到很多令人眼前一亮的代码,尤其是你写了几十行的代码,别人只用了简单几行的递归就实现的功能。下面我们就总结几个C语言中比较...
标题“CSS中边框使用负边距值的奇技淫巧”暗示了负边距在CSS中的独特应用,这些应用可能并不常见,但能够解决特定的布局挑战。描述提到,通过负边距可以进行布局调整和实现元素重叠,这些都是设计师和开发者可以利用...
在移动端UI自动化测试中,"正经奇技淫巧Havefun"这个标题暗示了我们将探讨一些巧妙而实用的技术,这些技术可能不广为人知,但能显著提高我们的工作效率。混合移动开发,特别是JavaScript开发,是现代移动应用开发的...
Git是一个 “分布式版本管理工具”,简单的理解版本管理工具:大家在写东西的时候都用过 “回撤” 这个 功能,但是回撤只能回撤几步,假如想要找回我三天之前的修改,光用 “回撤” 是找不回来的。...
### bash奇技淫巧 #### 简介 在日常的Linux使用过程中,熟练掌握Bash的一些技巧可以极大地提升工作效率。本文将分享一系列实用的Bash小贴士,旨在帮助那些经常与Linux命令行打交道的人们更好地利用Bash的强大功能...
这个压缩包文件"Python-收集到的一些src挖掘奇技淫巧"可能是包含了一系列用于Python源代码安全检查和分析的技巧和工具。下面我们将深入探讨一些相关的知识点。 1. **源代码分析**:这是对软件项目源代码进行的详细...