`
ajoo
  • 浏览: 452693 次
社区版块
存档分类
最新评论

getThis().getEvilAdvocate().setDead(getTrue())

阅读更多
code review过程中,看到这样的代码:
Pair<String, String> getFooAndBar() {
  ...
}


恶魔说,弄个Pair来表达FooAndBar不太容易理解,要不干脆弄个类把foo和bar封装起来,返回出来吧。

天使:“同意”。

下一版代码:
class FooAndBar {
  private final String foo;
  private final String bar;

  FooAndBar(String foo, String bar) {...}

  public String getFoo() {
    return foo;
  }

  public String getBar() {
    return bar;
  }
}


嗯。恶魔不爽了。这个FooAndBar纯粹就是为了从函数里面返回几个有逻辑关系的值的组合。它不是public,也没有工具要用java bean api来读它,有必要一本正经地搞getFoo(), getBar()吗?直接就两个foo,bar field,简单点不好?

天使:”反正就是IDE点几下,又不费事。“

恶魔:”可是,它占行数啊。我看着没用的代码眼晕啊“

天使:”getter可以控制只读“

恶魔:”不是有final呢嘛?“

天使:”用方法可以implement interface“

恶魔:”可是这里没有interface啊。就是一个纯值对象“

天使:”可以在getter()里面封装其它的逻辑,直接操作field没有这个灵活性“

恶魔:”搜索整个代码库,几乎95%的情况下,getter/setter都是简单的get/set。有必要为这个旷世罕见的灵活性增加复杂度么?“

天使:”getter是标准。sun推荐的。大家都这么干的“

恶魔:(音乐起,微笑)”紧张的生活会造成心跳加快,内分泌失调,皮肤老化,头发枯黄。所以当可以get日和set日的时候,让我们放开身心,勇敢地被日以及日吧!“


分享到:
评论
23 楼 liuhello 2008-08-20  
Quake Wang 写道
nihongye 写道
引用
它不是public,也没有工具要用java bean api来读它,有必要一本正经地搞getFoo(), getBar()吗?直接就两个foo,bar field,简单点不好?

加get set,propterty语法糖都不需要。简单简单,写java就非得将自己变白痴吗!

因为其他lib都是按照这种"白痴"的方式来读取javabean的属性,比如常见的struts, ognl,如果你直接用public field,和这些lib就很难配合,还得自己额外写一些转化的工具类。

其实这和整个编程语言的习惯有关系,比如在Java中,我们通常用isAdmin做方法名,而在ruby中,就会改用admin?做方法名,整个业界都是用getter/setter,哪怕它很白痴,我们也得随大流。Java语言想做大的改变,很难,毕竟要考虑到那么多历史兼容问题。


呼呼
有了标准就好办事啦
比如说几个版本的浏览器因为不是很遵循标准,搞得网页设计的人很是郁闷


如果在一个公司没有统一的标准,那就很难运行啦
当然好的标准固然很好  但是差的标准比没得的好
22 楼 radar 2008-08-15  
并行赋值啊。
我现在写多了javascript,不想写java代码啦。
21 楼 ajoo 2008-08-15  
caicai_45 写道
var FooAndBar = new {
Foo ="";
Bar="";
}
FooAndBar.Foo ="a";
FooAndBar.Bar="b";


这个是.net 3.0的语法,目前已经发布的版本已经可以这样写代码了,
类似这样的参数类(我取的名字),完全可以用这样的方式去做。
虽是语法糖,但是增加不少效率。

java有些地方太学院化。

还是不如这样爽:
run() {
  return (foo, bar);
}

(foo, bar) = run();
20 楼 caicai_45 2008-08-15  
var FooAndBar = new {
Foo ="";
Bar="";
}
FooAndBar.Foo ="a";
FooAndBar.Bar="b";


这个是.net 3.0的语法,目前已经发布的版本已经可以这样写代码了,
类似这样的参数类(我取的名字),完全可以用这样的方式去做。
虽是语法糖,但是增加不少效率。

java有些地方太学院化。
19 楼 liusong1111 2008-08-15  
真惨。ruby:
FooAndBar = Struct.new(:foo, :bar)


这个类就有了,反正暴露出来都是method,咱不怕
18 楼 ajoo 2008-08-15  
fyting 写道
主要的成本在于从FooAndBar.foo 到 FooAndBar.getFoo()的重构成本太高,其实需要getter、setter的理由就只有一个
引用
可以在getter()里面封装其它的逻辑,直接操作field没有这个灵活性

可惜java的实现太傻,啥大小写转换规则、is、has的,还不如一个property关键字。
public class FooAndBar{
    public String foo;    
}

想覆盖的时候再慢慢处理
public class FooAndBar{
    public String foo;

    @Porperty.Read
    public String getFoo(){
        println "get foo";
        return foo;
    }
}

这样就不错……Groovy里正是这样干的,但它还是沿用了get、set,没用annotation


很少见到有人在getFoo()里放逻辑的。九成以上都是"return foo"。

而且,“放逻辑”这件事本身也是值得怀疑的。如果你放的东西有副作用(side-effect),比如写个文件数据库什么的,那么对客户代码的影响很有可能是破坏性的。一般来说,我们都认为getFoo()是所谓的"Idempotent",也就是说调用两次和调用一次没区别,而且getFoo()应该是足够快的。可以写成:
if (obj.getFoo().canDoSomething()) {
  obj.getFoo().doSomething();
}

而不需要担心下面的重构会有行为变化:
Foo foo = obj.getFoo();
if (foo.canDoSomething()) {
  foo.doSomething();
}


而不放副作用的话,还有什么可放的?

至于说从foo到getFoo()重构的代价,首先,既然这种重构出现的可能性不大,那么代价大一点也可以接受。而且,我也不觉得有什么了不得的代价,非要用IDE自动化功能的话,可以走这个步骤:
1. 把foo改名成getTheFooThatIWillChangeToGetter。
2。增加getFoo()。
2. 全局替换getTheFooThatIWillChangeToGetter为getFoo()。
4。把getTheFooThatIWillChangeToGetter改回foo。
17 楼 ajoo 2008-08-14  
grandboy 写道
我们有一个项目涉及到CA的代码的,但是他们好像都是C的写法,就是直接把字段pbulic出来,我们在使用的时候,无法知道哪些字段是只读的,哪些是可写的.还有就是在使用一个类的时候,无法晓得哪些字段必须得赋值才能使用.如果是set, get, 至少可以知道set可以赋值,在使用的时候再进一步猜一下(之所以用猜是我们大家一般都比较懒,不愿意看文档,实在没有办法了才去找文档)就知道哪些必须要赋值. 

当然我也反对根本就没有必要的get和set, 有些地方一看就永远都用不到的get,set, 还是不要的为好. 因为大家都比较忙,一个类多看两行代码,就会费很多精力.

mutable的东西,不管有没有getter/setter都不好维护。
immutable的对象,一个final关键字就够了。

在古老的java 1.1.8时代,final关键字编译器处理得有问题,总出编译错误,所以要getter/setter来人为帮助。现在,java bean可以歇一歇了。
16 楼 acdc 2008-08-14  
看看古老而又充满活力的Objc-2.0
@interface FooAndBar : NSObject {
NSString* foo;
NSString* bar;

}
@property (readonly) NSString* foo;
@property (copy) NSString* bar;
@end

根据annotation,编译器自动生成 getter/setter.
Java需要反思。。。
我更要反思。。。
15 楼 grandboy 2008-08-14  
我们有一个项目涉及到CA的代码的,但是他们好像都是C的写法,就是直接把字段pbulic出来,我们在使用的时候,无法知道哪些字段是只读的,哪些是可写的.还有就是在使用一个类的时候,无法晓得哪些字段必须得赋值才能使用.如果是set, get, 至少可以知道set可以赋值,在使用的时候再进一步猜一下(之所以用猜是我们大家一般都比较懒,不愿意看文档,实在没有办法了才去找文档)就知道哪些必须要赋值. 

当然我也反对根本就没有必要的get和set, 有些地方一看就永远都用不到的get,set, 还是不要的为好. 因为大家都比较忙,一个类多看两行代码,就会费很多精力.
14 楼 didasoft 2008-08-14  
一般来说,这样的类根本没有存在的必要。
13 楼 fyting 2008-08-14  
主要的成本在于从FooAndBar.foo 到 FooAndBar.getFoo()的重构成本太高,其实需要getter、setter的理由就只有一个
引用
可以在getter()里面封装其它的逻辑,直接操作field没有这个灵活性

可惜java的实现太傻,啥大小写转换规则、is、has的,还不如一个property关键字。
public class FooAndBar{
    public String foo;    
}

想覆盖的时候再慢慢处理
public class FooAndBar{
    public String foo;

    @Porperty.Read
    public String getFoo(){
        println "get foo";
        return foo;
    }
}

这样就不错……Groovy里正是这样干的,但它还是沿用了get、set,没用annotation
12 楼 quaff 2008-08-14  
ajoo 写道
抛出异常的爱 写道
用map代替的话
IDE又不能返回想要的KEY
如果想把get set去的的话
只能在ide上想办法了。

难不成要运行时生成指定的代码?


我的办法就是:
final class FooAndBar {
  final Foo foo;
  final Bar bar;

  FooAndBar(Foo foo, Bar bar) {...}
}

用C++的术语,struct。

整这么麻烦还要多写一个类,直接返回数组
11 楼 nihongye 2008-08-14  
Quake Wang 写道
nihongye 写道
引用
它不是public,也没有工具要用java bean api来读它,有必要一本正经地搞getFoo(), getBar()吗?直接就两个foo,bar field,简单点不好?

加get set,propterty语法糖都不需要。简单简单,写java就非得将自己变白痴吗!

因为其他lib都是按照这种"白痴"的方式来读取javabean的属性,比如常见的struts, ognl,如果你直接用public field,和这些lib就很难配合,还得自己额外写一些转化的工具类。

其实这和整个编程语言的习惯有关系,比如在Java中,我们通常用isAdmin做方法名,而在ruby中,就会改用admin?做方法名,整个业界都是用getter/setter,哪怕它很白痴,我们也得随大流。Java语言想做大的改变,很难,毕竟要考虑到那么多历史兼容问题。

看帖不认真,前面已经说了,不需要javabean的方式来读它
10 楼 抛出异常的爱 2008-08-14  
ajoo 写道
sorphi 写道
ajoo 写道

我的办法就是:
final class FooAndBar {
  final Foo foo;
  final Bar bar;

  FooAndBar(Foo foo, Bar bar) {...}
}

用C++的术语,struct。


这个FooAndBar只能包内可见,那没法传递给客户端啦?

再,如果碰到了FooAndBarAndOther咋办?


本来就是包内的辅助数据结构,所谓的algebraic type。不需要对外公开。何况即使需要公开,把一切都变成public就是了,毕竟是项目自己用的,又不是jdk。

如果碰到Other,就再加一个field呗。

如果hibernate的话。。。
动态生成get与set
9 楼 ajoo 2008-08-14  
sorphi 写道
ajoo 写道

我的办法就是:
final class FooAndBar {
  final Foo foo;
  final Bar bar;

  FooAndBar(Foo foo, Bar bar) {...}
}

用C++的术语,struct。


这个FooAndBar只能包内可见,那没法传递给客户端啦?

再,如果碰到了FooAndBarAndOther咋办?


本来就是包内的辅助数据结构,所谓的algebraic type。不需要对外公开。何况即使需要公开,把一切都变成public就是了,毕竟是项目自己用的,又不是jdk。

如果碰到Other,就再加一个field呗。
8 楼 sorphi 2008-08-14  
ajoo 写道

我的办法就是:
final class FooAndBar {
  final Foo foo;
  final Bar bar;

  FooAndBar(Foo foo, Bar bar) {...}
}

用C++的术语,struct。


这个FooAndBar只能包内可见,那没法传递给客户端啦?

再,如果碰到了FooAndBarAndOther咋办?

7 楼 ajoo 2008-08-14  
Quake Wang 写道
nihongye 写道
引用
它不是public,也没有工具要用java bean api来读它,有必要一本正经地搞getFoo(), getBar()吗?直接就两个foo,bar field,简单点不好?

加get set,propterty语法糖都不需要。简单简单,写java就非得将自己变白痴吗!

因为其他lib都是按照这种"白痴"的方式来读取javabean的属性,比如常见的struts, ognl,如果你直接用public field,和这些lib就很难配合,还得自己额外写一些转化的工具类。

其实这和整个编程语言的习惯有关系,比如在Java中,我们通常用isAdmin做方法名,而在ruby中,就会改用admin?做方法名,整个业界都是用getter/setter,哪怕它很白痴,我们也得随大流。Java语言想做大的改变,很难,毕竟要考虑到那么多历史兼容问题。

不用写工具类。如果最终需要和这些白痴工具集成,我就refactor一下好了,多大点事?

事实上,这个类在后续的重构中又消失了,这些额外的getter/setter所付出的代价完全没有得到任何回报。
6 楼 ajoo 2008-08-14  
抛出异常的爱 写道
用map代替的话
IDE又不能返回想要的KEY
如果想把get set去的的话
只能在ide上想办法了。

难不成要运行时生成指定的代码?


我的办法就是:
final class FooAndBar {
  final Foo foo;
  final Bar bar;

  FooAndBar(Foo foo, Bar bar) {...}
}

用C++的术语,struct。
5 楼 QuakeWang 2008-08-14  
nihongye 写道
引用
它不是public,也没有工具要用java bean api来读它,有必要一本正经地搞getFoo(), getBar()吗?直接就两个foo,bar field,简单点不好?

加get set,propterty语法糖都不需要。简单简单,写java就非得将自己变白痴吗!

因为其他lib都是按照这种"白痴"的方式来读取javabean的属性,比如常见的struts, ognl,如果你直接用public field,和这些lib就很难配合,还得自己额外写一些转化的工具类。

其实这和整个编程语言的习惯有关系,比如在Java中,我们通常用isAdmin做方法名,而在ruby中,就会改用admin?做方法名,整个业界都是用getter/setter,哪怕它很白痴,我们也得随大流。Java语言想做大的改变,很难,毕竟要考虑到那么多历史兼容问题。
4 楼 nihongye 2008-08-14  
引用
它不是public,也没有工具要用java bean api来读它,有必要一本正经地搞getFoo(), getBar()吗?直接就两个foo,bar field,简单点不好?

加get set,propterty语法糖都不需要。简单简单,写java就非得将自己变白痴吗!

相关推荐

    getaddrinfo.c 内部代码

    《深入解析getaddrinfo.c:C语言在Linux DNS解析中的应用》 在计算机网络编程中,DNS(Domain Name System)是互联网的一项基础服务,它负责将人类可读的域名转换为IP地址。在Linux系统中,`getaddrinfo()`函数是...

    getPdf.pdf

    getPdf.pdf

    HTML5小游戏【算术游戏-找到相加等于36的组合get36】游戏源码分享下载 - get36.zip

    游戏源码分享下载 --- get36.zipHTML5小游戏【算术游戏--找到相加等于36的组合get36】游戏源码分享下载 --- get36.zipHTML5小游戏【算术游戏--找到相加等于36的组合get36】游戏源码分享下载 --- get36.zipHTML5小...

    动态获取数据库中的数据作为loadrunner的参数的GetData.dll

    GetData.dll 版本:0.2 作者:kernzhang 测试结果:在SQL server2k测试通过、在postgre上测试通过 ,有网友在oracle上测试通过(但未认证) 本程序采用了ODBC3版本编写,原则上适合于任何一个关系型数据库

    Get.Smart.Season 1.srt

    Filename.....: Get.Smart.1965.S01E30.The.Last.One.In.Is.A.Rotten.Spy.avi Filesize.....: 183,820,288 bytes Runtime......: 25:25.762 (36582 frames) Video Codec..: XviD 1.1.2 Final (B-VOP//) Video Bit...

    GetAdmin.exe

    用于提升用户等级,获得管理员权限,是的完全操控肉鸡

    //通过域名得到IP//通过域名得到IP

    Function string GetIp(string name) Library "GetNet.dll" //得到本机IP地址 Function string GetLocalIp() Library "GetNet.dll" //通过ip得到域名 Function string GetName(string ip) Library "GetNet.dll" //...

    GetData.Graph.Digitizer.v2.24

    《GetData.Graph.Digitizer.v2.24:高效图片数据提取工具详解》 在现代科研工作中,数据分析是一项至关重要的任务,而 GetData.Graph.Digitizer.v2.24 正是一款专为此目的设计的强大软件。这款工具能够从图像中精确...

    路径getUrl.js

    获取项目路径js方法,配置地图时有用到。获取项目路径js方法,配置地图时有用到。

    getcode.asp 图片验证码

    ASP图片验证码,用于验证提交表单的合法性。验证码以图片的形式输出显示。

    Advanced GET EOD.v9.1.0.19.rar

    Advanced GET — 波浪分析工具 综观全世界股市的庄家无论是调研分析或操盘技术都是精益求精,甚至标准到令人目瞪口呆的地步,他们作为市场主力使用Advanced GET高级数学模型客观智能数浪,严格按照有关的技术和设定...

    get-docker.sh

    此docker安装脚本为官方提供的,可以从网上下载,此处直接上传。安装docker客户端,get-docker.sh

    get-docker.sh docker安装脚本

    get-docker.sh docker安装脚本,可直接执行 sh get-docker.sh --mirror Aliyun 安装

    python2.7中所用的get-pip.py文件+安装方法

    `get-pip.py`是一个Python脚本,它的主要作用是为没有预装`pip`的Python环境安装`pip`。在Python 2.7中,由于某些系统可能没有默认提供`pip`,或者`pip`版本过低,`get-pip.py`就显得非常有用。这个脚本可以下载并...

    GetData.exe

    GetData 图片曲线数据提取软件,很好用的图形曲线提取类软件

    get-pip.py

    用于安装python的pip插件,下载后运行该文件即可:'python get-pip.py'. 若没有权限则使用 'sudo python get-pip.py' (linux macOS)。

    getPDF.jsp.pdf

    getPDF.jsp.pdf

    get-pip.py 安装pip

    get-pip.py 安装pip

    GetConnection.java

    GetConnection.java

    GetSign.apk

    GetSign.apk

Global site tag (gtag.js) - Google Analytics