http://www.iteye.com/topic/39694?page=1
class Details {
double getBalance();
double getFixed();
double getVariable();
double getSpendDown();
...
//各种getter以及其他相关的逻辑
}
class Details {
double getBalance();
double getFixed();
double getVariable();
double getSpendDown();
...
//各种getter以及其他相关的逻辑
}
现在业务逻辑需要对一些property做求和操作,求overallBalance, overallFixed之类的。
没什么了不起的,一个for循环分分钟搞定:
Java代码
static double getOverallBalance(Details[] arr){
double sum = 0;
for(int i=0; i<arr.length; i++) {
sum += arr[i].getBalance();
}
}
static double getOverallBalance(Details[] arr){
double sum = 0;
for(int i=0; i<arr.length; i++) {
sum += arr[i].getBalance();
}
}
同理,对overallFixed,代码大同小异,copy-paste先。
Java代码
static double getOverallFixed(Details[] arr){
double sum = 0;
for(int i=0; i<arr.length; i++) {
sum += arr[i].getFixed();
}
}
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接口,如下:
Java代码
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]);
}
}
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]);
}
}
娜爱思啊。有比这代码更优雅的么?
然后各个求和的代码变成:
Java代码
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();
}
});
....
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(),最终的语法会是:
Java代码
double overallBalance = sum(details, "balance");
double overallBalance = sum(details, "balance");
语法足够简单了,但是重构的时候就麻烦了,也没有code-completion可用。
尴尬阿。这么一个简单的for loop,用匿名类重构似乎不值得。但是就任由这七个(也许回头还会更多)长得一模一样的for loop这么站在这气我?
走投无路,开始琢磨奇技淫巧了。
先声明一个接口,来包含所有需要sum的property getter。
Java代码
private interface IDetails {
double getBalance();
double getFixed();
double getVariable();
double getSpendDown();
...
//所有其它需要做sum的getter
}
private interface IDetails {
double getBalance();
double getFixed();
double getVariable();
double getSpendDown();
...
//所有其它需要做sum的getter
}
然后让Details实现IDetails。Details的代码不用变。
Java代码
class Details implements IDetails {
...
//代码不变
}
class Details implements IDetails {
...
//代码不变
}
戏肉来了。写一个dynamic proxy,来封装sum逻辑。
Java代码
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);
}
});
}
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的语法可以被简化为如下:
Java代码
double overallBalance = sumOf(arr).getBalance();
double overallFixed = sumOf(arr).getFixed();
...
double overallBalance = sumOf(arr).getBalance();
double overallFixed = sumOf(arr).getFixed();
...
而且,再需要sum新的property,只需要把这个getter放进IDetails接口,就大功告成了。
分享到:
相关推荐
今天小编就为大家分享一篇python 用for循环实现1~n求和的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
matlab求和函数∑用什么函数如∑(n^2+7n)^3 n从1~100
for循环实现打印1-100内素数并求和
python 用for循环实现1~100之间的偶数求和 示例
简单的数学计算代码,奇数求和,适用于新手入门学习代码
python 用for循环实现1~100求和 示例
1306字符串数字求和ch-for循环.c
给定一个正整数a,以及另外的5个正整数,问题是:这5个整数中,小于a的整数的和是多少? 输入要求 输入一行,只包括6个小于100的正整数,其中第一个正整数就是a。 输出要求 输出一行,给出一个正整数,是5个数中...
for循环的经典例子就是连续求和了:1+2+3+……+100,讲了一个多小时,还是有同学不会。做程序得有思想,有的同学一直敲键盘,也没搞出来。在做这个求和之前,我们要思考一下,求和其实就是连续的累加,当变量$i自增...
本程序使用了 for 和 while 两种条件表达式!
C语言实现求1+2+3+……+100的和,要求分别用while、do while、for循环实现。.txt
for while 循环求和
卷积运算:取x(t)和h(t)的长度为nx,nh。平移量n=nh+nx-1,利用for和if语句实现倒序求和运算。外循环用一个for语句实现平移,通过在求和时取数组元素的顺序实现倒序求和
c代码-阶乘求和(for循环)
for, do while, while写的九九乘法表 for循环写的打印菱形,正方形 for循环打印的求和等 最全的for学习资料
利用MATLAB内置的函数自动查询所输入的参数个数,再利用for循环求和。 小题2 随机变量求最优解 具体内容参考参考正课课件。优化的函数是一个凸函数,因此其局部最优解即为函数的全局最优解。 练习1 创建函数people对...