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接口,就大功告成了。
分享到:
相关推荐
/* 使用for循环求和 for (i = 1; i ; i++) { num += i; } */ /* 使用while循环求和 while (i ) { num += i; i++; } */ // 使用do...while循环求和 do { num += i; i++; } while (i ); ...
Python中可以使用for循环实现累加求和 for循环语法: for 变量 in range(x): 循环需要执行的代码 如下实现1到n求和: def main(): sum = 0 # 定义变量做累加器 n = int(input('n=')) #\u4ece\u952e\u76d8\u4e0a...
### Python使用For循环实现1~n求和的实例解析 #### 核心知识点:Python For循环及求和应用 在Python编程中,`for`循环是一种常用的迭代结构,用于重复执行一段代码直到满足某个条件为止。本文将详细介绍如何利用...
for n = 1:100 term = (n^2 + 7*n)^3; result = result + term; end ``` 这里,我们初始化`result`为0,然后遍历1到100的每个n,计算求和项,并将其累加到`result`。 另外,MATLAB的`arrayfun`函数可以处理向量化...
例如,一个简单的`For`循环求和可能如下: ```vb Dim sum As Integer Dim i As Integer sum = 0 For i = 1 To 10 ' 假设我们要对1到10的整数求和 sum = sum + i Next i MsgBox "The sum is: " & sum ``` 在这个...
例如,使用for循环求和问题时,可以先初始化求和变量,然后通过循环累加求和,最终得到结果。在求解方程迭代求根问题时,可以利用for循环进行迭代计算,直到满足精度要求。而在图案输出问题中,for循环可以控制循环...
#### 示例2:for循环求和 ```java class SumTest { public static void main(String[] args) { int sum = 0; for (int i = 1; i ; i++) { sum += i; } System.out.println(sum); } } ``` 此例中使用了`for`...
本篇文章将深入探讨C语言中的for语句,并通过实例演示如何用for循环实现求和操作。 for语句是C语言中的一个非常强大且常用的循环结构,适用于执行固定次数或基于特定条件的循环。它的基本语法结构如下: ```c for ...
本文将深入探讨如何使用for循环来实现奇数求和的功能,这是一项适合初学者上手的练习。 首先,我们需要理解for循环的基本结构。for循环是一种迭代控制结构,它允许我们在满足特定条件时重复执行一段代码。其基本...
1. **使用for循环求和**: ```matlab sum = 0; for i = 1:100 sum = sum + i; end disp(sum); ``` 这段代码首先初始化一个变量`sum`为0,然后通过`for`循环从1迭代到100,每次迭代时将当前的`i`值累加到`sum...
for循环实现打印1-100内素数并求和
例如,使用For循环遍历数组,每一轮累加当前元素值到总和变量中。 - 示例代码: ```vb Dim arr() As Integer = {1, 2, 3, 4, 5} Dim sum As Integer = 0 For i As Integer = LBound(arr) To UBound(arr) sum +...
python 用for循环实现1~100之间的偶数求和 示例
一、for循环求和 `for`循环在MATLAB中用于按顺序迭代一个特定范围内的数值。当你知道要迭代多少次时,通常选择`for`循环。例如,如果你想计算1到10的整数之和,可以这样写: ```matlab sum = 0; for i = 1:10 sum...
本程序着重介绍了如何在VB中利用`for`和`while`循环实现数据的求和功能。 `For`循环是编程中最常见的循环结构之一,它的语法形式为: ```vb For counter = start To end [Step step] ' 循环体代码 Next ``` 其中,...
16. **for循环求和**:`for i in range(1,20,3)`循环的初值是1,终值是20,步长是3。程序执行后,`sum`的值为1+4+7+10+13+16+19,即`sum=63`。 17. **“百鸡百钱”问题**:这是一个经典的数学问题,涉及整数解的...
// 使用for循环求和 let totalSumFor = 0; for (let i = 0; i ; i++) { totalSumFor += numbers[i]; } // 使用forEach方法求和 let totalSumForEach = 0; numbers.forEach(num => totalSumForEach += num); ``` ...
python 用for循环实现1~100求和 示例