论坛首页 Java企业应用论坛

奇技淫巧?

浏览 47009 次
锁定老帖子 主题:奇技淫巧?
该帖已经被评为良好帖
作者 正文
   发表时间:2006-12-20  
aardvark 写道
怎么都是“静态”方法啊?

在ruby里一般是
overall_balance = arr.inject(0) {|s,x| s += x.balance}


或者给arr添加sum,当然添加给Array也行
def arr.sum(f)
  self.inject(0) {|s,x| s += x.send(f)}
end

overall_balance = arr.sum(:balance)
overall_variable = arr.sum(:variable)


在java里
class Summary {
  private double overallBalance = 0;
  private double overallFixed = 0;
  private double overallVariable = 0;
  private double overallSpendDown = 0;

  public Summary(Details[] arr) {
    for (int i = 0; i < arr.length; i++) {
      overallBalance += arr[i].getBalance();
      overallFixed += arr[i].getFixed();
      overallVariable += arr[i].getVariable();
      overallSpendDown += arr[i].getSpendDown();
    }
  }

  // getters
  //...
}


因为这么做太简单所以不愿意用?还是一定要用Java去模仿Ruby?


不同地。我们不是要同时得到所有的property的和,而是要在不同的地方不同的时间取得不同的和。所以难以一个循环搞定。不管三七二十一每次都是对所有东西求和感觉有点笨,而且每增加一个求和的可能就要回来改动已有的代码。
0 请登录后投票
   发表时间:2006-12-21  
ajoo 写道

不同地。我们不是要同时得到所有的property的和,而是要在不同的地方不同的时间取得不同的和。所以难以一个循环搞定。不管三七二十一每次都是对所有东西求和感觉有点笨,而且每增加一个求和的可能就要回来改动已有的代码。


因为你有个class Details,把这些properties封装在一起,所以我假定他们总是作为一个整体有意义的。可是你的数据的nature不是这样,你需要在不同的地方不同的时间取不同的和,那这些数据其实是有两个维度。
既然这样,还有更笨的办法:二维数组。当然二维数组不一定是合适的解决方案,要看你的数据的nature,我只是提供一个思路。

我想说的另一点:不管用什么实现,这些Details既然放在一起,并且上面还有一些动作,那就应该考虑把它们看成一个model,除非你有特别的理由不这么做。
class DetailsAggregation {
  //一维数组,二维数组,ArrayList, what ever
}

这样的话,即便你用Dynamic Proxy来实现,也不再是一个static method,这样更OO一点。

基本上写Java我是反对在业务逻辑里面用框架技术,因为将来维护你的代码的人可能连reflection都没有听说过。写Ruby的时候,我遵循DRY;写Java的时候,则是KISS(Keep It Simple and Stupid)。
0 请登录后投票
   发表时间:2006-12-21  
所以我觉得这是个很有趣的例子。这里面每个人的设计倾向可能都会有所反映。

目前为止,已经有:

老老实实地for
用Getter回调
dyn proxy
做个Summary类,然后一次计算所有的和
beanutils反射

等方法。

我完全理解kiss的意义。只不过这个例子在我的心里,kiss和dry这两个矛盾的目标几乎是不分胜负。要不说尴尬呢。


这些选择中,我如果没有用dyn proxy,可能会选择最老实的for loop。Summary这种方法不太合口味亚。

0 请登录后投票
   发表时间:2006-12-21  
bencode 写道

嘿嘿, 还有, 我觉得重复不是看简单的代码相似, 而应该从语义,或逻辑角度上去抽像。

同意这个观点。
不过另外一方面,也的确说明了,Java的语言在某些时候是不够简洁的。
不过如果真的在形式上简洁,也许就语言的集合会比较庞大?
需要权衡。
也是一个可发展的方向。比如Java5例引入的for (ELEMENT:SET) 的语法,也是朝着简洁性的方向迈的一小步。
0 请登录后投票
   发表时间:2006-12-21  
Lucas Lee 写道
bencode 写道

嘿嘿, 还有, 我觉得重复不是看简单的代码相似, 而应该从语义,或逻辑角度上去抽像。

同意这个观点。
不过另外一方面,也的确说明了,Java的语言在某些时候是不够简洁的。
不过如果真的在形式上简洁,也许就语言的集合会比较庞大?
需要权衡。
也是一个可发展的方向。比如Java5例引入的for (ELEMENT:SET) 的语法,也是朝着简洁性的方向迈的一小步。

Getter接口就是从语义逻辑角度抽象地。
0 请登录后投票
   发表时间:2006-12-21  
其实,我另外一个想表达的意思是,

java里面有一些东西不见得有标准答案的。这个例子中所有的解决办法都有这样那样的缺点。很难明显地看出哪个方法绝对地优越。

而程序员往往都是比较主观的人群,对一些问题有强烈的倾向,比较合理的也许是承认人是不同的,可以有不同观点的。认识到自己的一些偏爱只是自己的主观偏爱,不要试图强加给别人。对这种不是大是大非的问题(一个小模块不管内部怎么实现,只要测试够了,对外接口合理,不就行了?),学会求同存异,从牛角尖钻出去。
0 请登录后投票
   发表时间:2006-12-21  
引用
不过另外一方面,也的确说明了,Java的语言在某些时候是不够简洁的。


Java语言不够简单, 和他是静态语言有很大的关系。 强类型。

使用过Ruby 或者 Javascript 的。 就会被其简洁灵活的语句所吸引。
0 请登录后投票
   发表时间:2006-12-21  
aardvark 写道
基本上写Java我是反对在业务逻辑里面用框架技术,因为将来维护你的代码的人可能连reflection都没有听说过。写Ruby的时候,我遵循DRY;写Java的时候,则是KISS(Keep It Simple and Stupid)。

支持一下aardvark,强迫目前Java不愿意做的事情,这个东西用起来很苦。
不过楼主的反射和内部类用的真是轻车熟路,学习一下
0 请登录后投票
   发表时间:2006-12-21  
ajoo 写道
所以我觉得这是个很有趣的例子。这里面每个人的设计倾向可能都会有所反映。

目前为止,已经有:

老老实实地for
用Getter回调
dyn proxy
做个Summary类,然后一次计算所有的和
beanutils反射

弱问下:"beanutils反射"具体指什么方法?
另外,这样不也很好么?
public static double sumOf(Details[] arr,String name)throws Throwable{
        Method m =Details.class.getMethod(name);
        double sum =0;
        for(Details d:arr) sum +=(Double)m.invoke(d);
        return sum;      
    }

调用也很简单啊,也看不出什么坏处:
sumOf(details,"getFixed");
0 请登录后投票
   发表时间:2006-12-21  
Eastsun:

引用
弱问下:"beanutils反射"具体指什么方法?
另外,这样不也很好么?


Beanutil 是Apache Commons 项目的一个子项目,他提供一些很方便的java bean反射的功能

比如里面有个 PropertyUtils类 ,可以很容易取得一个 java bean 的 属性

Object PropertyUtils#getProperty(java.lang.Object bean, java.lang.String name)


具体的可参考
   http://jakarta.apache.org/commons/index.html
以及
   http://jakarta.apache.org/commons/beanutils/
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics