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

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()`函数是...

    GetData.Graph.Digitizer.v2.24

    《GetData.Graph.Digitizer.v2.24》是一款强大的数据提取工具,专为科研和工程领域的用户设计。这款软件能够帮助用户从各种图形文件中精确地获取曲线的坐标数据,以便进行进一步的数据分析和处理。在学术研究和工程...

    //通过域名得到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" //...

    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

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

    路径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

    python3.6 get-pip.py

    curl https://bootstrap.pypa.io/pip/3.6/get-pip.py -o get-pip.py python get-pip.py

    get-pip.py 安装pip

    get-pip.py 安装pip

Global site tag (gtag.js) - Google Analytics