V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wsy190
V2EX  ›  程序员

写程序这么精简真的好吗?

  •  5
     
  •   wsy190 · 2019-08-30 09:36:07 +08:00 · 19314 次点击
    这是一个创建于 1909 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有一个同事写代码特别精简。。如:

    public OutVoGlobal list(BatteryOrderDTO dto, UserInfo user) {

    return new OutVoGlobal(EnumRetCode.SUCCESS).setData(orderMapper.list(dto.setBelong(user.getUserNo())));

    }
    

    之后这段代码有一些问题,让我来修改这段代码。。我就觉得这段代码的可读性特别的差。昨天和他讨论了一下,他觉得代码行数多影响阅读,他这样他看起来很舒服。以下是我加了判断后的:

    public OutVoGlobal list(BatteryOrderDTO dto, UserInfo user) {

        OutVoGlobal outVoGlobal=new OutVoGlobal(EnumRetCode.SUCCESS);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if(!StringUtils.isEmpty(dto.getStartTime())){
            try {
                sdf.parse(dto.getStartTime());
                dto.setStartTime(dto.getStartTime()+" 00:00:00");
            } catch (ParseException e) {
                dto.setStartTime("");
            }
        }
        if(!StringUtils.isEmpty(dto.getEndTime())){
            try {
                sdf.parse(dto.getEndTime());
                dto.setEndTime(dto.getEndTime()+" 23:59:59");
            } catch (ParseException e) {
                dto.setEndTime("");
            }
        }
        dto.setBelong(user.getUserNo());
        PageHelper.startPage(dto.getPageNo(), dto.getPageSize());
        List<BatteryOrder> list=orderMapper.list(dto);
        outVoGlobal.setData(list);
        return outVoGlobal;
    
    }
    

    如果没有改动的话这段代码我一定会这么写:

    public OutVoGlobal list(BatteryOrderDTO dto, UserInfo user) {

        OutVoGlobal outVoGlobal=new OutVoGlobal(EnumRetCode.SUCCESS);
        dto.setBelong(user.getUserNo());
        PageHelper.startPage(dto.getPageNo(), dto.getPageSize());
        List<BatteryOrder> list=orderMapper.list(dto);
        outVoGlobal.setData(list);
        return outVoGlobal;
    }
    

    确实是代码增加了很多行,但是我觉得这样写当我要进行断点调试的时候会很舒服。而且当别人要改我代码的时候也能一目了然。。 然后他说如果你要加上面的新需求的话可以这么写

    public OutVoGlobal list(BatteryOrderDTO dto, UserInfo user) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if(!StringUtils.isEmpty(dto.getStartTime())){
            try {
                sdf.parse(dto.getStartTime());
                dto.setStartTime(dto.getStartTime()+" 00:00:00");
            } catch (ParseException e) {
                dto.setStartTime("");
            }
        }
        if(!StringUtils.isEmpty(dto.getEndTime())){
            try {
                sdf.parse(dto.getEndTime());
                dto.setEndTime(dto.getEndTime()+" 23:59:59");
            } catch (ParseException e) {
                dto.setEndTime("");
            }
        }
       return new OutVoGlobal(EnumRetCode.SUCCESS).setData(orderMapper.list(dto.setBelong(user.getUserNo()))
    }
    

    我一想,这么写也可以呢。但是我还是觉得他最后那个 return 看起来太麻烦了,我又没有理由反驳他。 其实在写代码的过程中我发现他有好多的习惯我都不习惯。比如说我一般都是这么写:

    OutVoGlobal outVoGlobal=new OutVoGlobal(EnumRetCode.SUCCESS);

    …… if(StringUtils.isEmpty(XXX)){

    outVoGlobal.setCode("1000");
    outVoGlobal.setInfo(XXX+"不能为空");
    // return outVoGlobal.setCode("1000").setInfo(XXX+"不能为空");
    return outVoGlobal;
    

    } if(StringUtils.isEmpty(SSSS)){

    outVoGlobal.setCode("1000");
    outVoGlobal.setInfo(SSS+"不能为空");
    return outVoGlobal;
    

    } …… return outVoGlobal;

    如果我也用了插件的话我会这么写

    OutVoGlobal outVoGlobal=new OutVoGlobal(EnumRetCode.SUCCESS);

    …… if(StringUtils.isEmpty(XXX)){

    return outVoGlobal.setCode("1000").setInfo(XXX+"不能为空");
    

    } if(StringUtils.isEmpty(SSSS)){

     return outVoGlobal.setCode("1000").setInfo(SSS+"不能为空");
    

    } …… return outVoGlobal;

    他如果写的话会这么写:(加了 @Accessors(chain = true)的前提下)

    …… if(StringUtils.isEmpty(XXX)){

    return new OutVoGlobal().setInfo(XXX+"不能为空").setCode("1000");
    

    } if(StringUtils.isEmpty(SSSS)){

     return new OutVoGlobal().setInfo(SSS+"不能为空").setCode("1000");
    

    } …… return new OutVoGlobal(EnumRetCode.SUCCESS);

    大家觉得是先把这个变量在开始的时候声明了好还是在用到的时候直接返回好呢?
    

    然后还有别的:

    if (userData == null) return outError(outVo, EnumRetCode.NO_REGISTER, "未查询到用户信息, userNo -->{}", user.getUserNo()); else if (!userData.getPwd().equals(pwd = encrypt(user.getUserNo(), user.getPwd())))

            return outError(outVo, EnumRetCode.ERROR_PWD, "密码错误, userNo -->{} | pwdData -->{} | pwdInput -->{}", user.getUserNo(), userData.getPwd(), pwd);
    

    else if (!StringUtils.isEmpty(userData.getOpenId()) && !openid.equals(userData.getOpenId())) // 删除上一个用户信息

            redisUtil.delMapKey(param.getUserKey() + userData.getOpenId(), "userInfo", "null");
    

    这种。。。if 和 else if 他后面都跟了一行,之后 他就省去了{} 他特别喜欢这么写代码。可是我每次看都要自己看一下才知道他是怎么做的。。虽然说他只写了一行,但是我看的时候还是会脑补成我写的那样。。

    if (!"0000".equals(TokenUtil.verify(outVo, tokenMap).getCode()))

            return outVo;
    

    他还喜欢把变量声明写在一行上。。

    String openid = (String) tokenMap.get("openid"),userMapKey;

    这样的代码我找 userMapKey 就很懵逼。。

    再贴一段代码: if (userMap == null || userMap.get("userInfo") == null) {

            // 获取已绑定的用户信息
            if ((user = userInfoDao.getByOpenId(openid)) == null) return null;
    
            redisUtil.saveMapSecond(userMapKey, "userInfo", JSONObject.toJSONString(user), appParam.getCacheTime());
    
        } else
    
            user = JSONObject.parseObject(userMap.get("userInfo").toString(), UserInfo.class);
    

    反正我是看不习惯。。。大家觉得呢。这么写是好还是不好呢。。

    第 1 条附言  ·  2019-08-30 12:01:14 +08:00
    讲真,我是抱着讨论的态度来发的。
    因为自己也不清楚到底哪种方法合适,因为我觉得他说的也有道理,但是我也觉得我这么写还行。
    当然了帖子绝对有我个人的主观倾向,我更愿意大家说我这么写好,所以我要在帖子里让大家更同意我的观点。
    我有问题就改。他有问题的话我就不去模仿。
    其实我主观认为两个人都有问题,我写的代码逻辑多了也臃肿,他写的让别人维护和 debug 也挺麻烦,就和之前有人回帖那样似的。两个人中和一下,可以把大的功能写在单独的方法里。
    149 条回复    2019-08-31 21:09:32 +08:00
    1  2  
    wsy190
        1
    wsy190  
    OP
       2019-08-30 09:42:15 +08:00
    为了讨论这件事昨天还特意注册了一个账号。。。
    第一发帖不太会用这个编辑器。。。
    delectate
        2
    delectate  
       2019-08-30 09:50:41 +08:00   ❤️ 12
    滥用语法糖、缩行、炫技的程序员,我们上次已经炖汤了,味道不错,就是肉有点塞牙。

    下次再碰到这样的程序员,直接给我们送过来就行。
    iiicarus
        3
    iiicarus  
       2019-08-30 10:04:04 +08:00   ❤️ 1
    这样挺好的
    shawnbluce
        4
    shawnbluce  
       2019-08-30 10:04:06 +08:00   ❤️ 11
    有一句话:“代码是写给人看的,顺便给机器执行”
    gwybiaim
        5
    gwybiaim  
       2019-08-30 10:09:24 +08:00   ❤️ 2
    所有的目的是为了,可读性、可维护性。在很多代码规范里,长长的一行是不被推荐的。你也提到了,可读性差、不方便 debug,更关键的是,如果拆开多行,天然有变量名,对读代码来说,非常有利
    wsy190
        6
    wsy190  
    OP
       2019-08-30 10:25:40 +08:00   ❤️ 1
    @shawnbluce 他是觉得这么写比写好多行看起来方便。。
    而我是觉得看很多行方便容易理解,看他那一行很麻烦,还得挨个分析。。
    pingpingping
        7
    pingpingping  
       2019-08-30 10:30:05 +08:00   ❤️ 1
    据说古龙当初为了酒钱,老是分行分段么。。
    还是金庸的排版好经典啊
    0x11901
        8
    0x11901  
       2019-08-30 10:55:22 +08:00
    有的人总总觉得他有一点个人的理解,他要把他的那个理解给实现,他的理解就是小鱼人点四级跳,然后带个点金手来打架。这种理解他觉得很到位,其实没什么用的。你先把最普通的那种打法打好,再去尝试自己的想法……
    zhanggg
        9
    zhanggg  
       2019-08-30 10:56:31 +08:00
    建议让那个老哥看看人月神话,软件工程本质还是工程,自己一个人炫技不考虑其他人感受,完全就是 XX
    当然一人全栈的项目除外,你爱咋写咋写
    IceChen
        10
    IceChen  
       2019-08-30 11:01:21 +08:00
    链式调用,没什么问题。。
    好的链式调用,连起来,就是一句话。。
    wsy190
        11
    wsy190  
    OP
       2019-08-30 11:02:55 +08:00
    @0x11901
    其实这是个 98 年的小同事写的。。(我 94。。)
    wysnylc
        12
    wysnylc  
       2019-08-30 11:08:29 +08:00   ❤️ 2
    链式调用,没任何问题啊
    链式调用一样可以写注释
    而且第二段代码和第一段完全不一样,第一段只是单纯的 set 第二段有大量的判断逻辑能一样比较?
    链式调用也是炫技?我活在 2000?
    LuciferGo
        13
    LuciferGo  
       2019-08-30 11:08:39 +08:00
    如果是刚开始写代码的人,还是建议改过来,代码的可读性、可维护性还是很重要的,长长的写一行自己看有时候都不方便看,更不要说交给后续接手的人了。
    wysnylc
        14
    wysnylc  
       2019-08-30 11:09:33 +08:00
    还有 SimpleDateFormat 高并发下存在问题,都已经禁用的东西你还敢用
    你多久没有学过新技术?
    wsy190
        15
    wsy190  
    OP
       2019-08-30 11:12:03 +08:00
    @IceChen
    我是觉得这句话干的事情有点多。不过确实是没问题。。刚用阿里编码规范扫描了一下,都没问题。。。但是我觉得第一次读起来不算太习惯。。

    new OutVoGlobal(EnumRetCode.SUCCESS).setData(orderMapper.list(dto.setBelong(user.getUserNo()))
    1:新建了一个 OutVoGlobal
    2:给 OutVoGlobal 赋了一个 EnumRetCode.SUCCESS 的值
    3:给 OutVoGlobal 的 Date 赋值 A
    4:A 是用 orderMapper.list(dto)查的
    5:给 dto 设置了一个 belong,belong 的值是从 user 中拿的。。

    我改他代码是因为他 dto 中的东西需要重新判断一下。
    dto 里面有个开始时间和结束时间,前端有可能传过来的是汉字,我需要 try catch 一下,如果发生异常我把这个字段改为空字符串。确实是可以在他这句话之前加判断。
    但是按照正常逻辑来讲应该是在他代码的第 5 步来判断吧。。

    其实我还是坚持他这么写可读性不好。。但是确实是可以在他这句话之前加判断。(也不清楚是不是自己水平不行。。不过我总觉得再让我重新来一遍我还是得看到第五步。。)
    wsy190
        16
    wsy190  
    OP
       2019-08-30 11:14:02 +08:00
    @wysnylc 小作坊公司。。。刚工作一年多。。技术确实是不到位。。大佬喜怒。。
    closedevice
        17
    closedevice  
       2019-08-30 11:18:02 +08:00
    记住一句话,代码时写给人看的,顺便给机器执行.对于团队工程,通用的可阅读性是第一要义.
    wysnylc
        18
    wysnylc  
       2019-08-30 11:18:52 +08:00
    @wsy190 #16 非大佬,只是觉得你纠结的东西微不足道
    写代码多写注释,代码千变万化注释一行足以
    如果给你一个十万行代码的类,但是注释就一句 输入 1 返回 1 你觉得哪个更好?
    代码只要不出错没并发就是好代码,写法因人而异
    记住有一万个哈姆雷特,你只是其中一个罢了
    alphatoad
        19
    alphatoad  
       2019-08-30 11:19:51 +08:00 via iPhone   ❤️ 2
    没有可读性的代码就是屎山
    queuey
        20
    queuey  
       2019-08-30 11:25:35 +08:00   ❤️ 1
    没觉得第一个有啥问题啊,只要写好注释我认为第一个写的挺好的
    Heylion
        21
    Heylion  
       2019-08-30 11:26:59 +08:00
    @wysnylc 他这里线程私有的,怎么有并发问题
    eGlhb2Jhb2Jhbw
        22
    eGlhb2Jhb2Jhbw  
       2019-08-30 11:28:18 +08:00
    你给他的意见解决方法是“展开写”
    他给你的意见解决方法是“条件语句或与当前方法主要逻辑无关的代码尽量抽离出另外一个方法”

    你俩的问题不就都解决了吗?
    不会因为展开写导致本方法的主要逻辑难读,也不会因为有人需要知道更详细的逻辑而难读。
    no1xsyzy
        23
    no1xsyzy  
       2019-08-30 11:30:15 +08:00
    @wysnylc 这个问题是:信息流的顺序和代码中的顺序不符,所以说了多少次,使用从左到右的书写的语言,函数调用不应该是 func(args) 而应该是 args|func,不然就必然导致分步执行容易理解,但对低级语言不友好还得栈上放东西。
    但这涉及多参问题……柯里化的话这种情况反而变成 argn|(...|(arg2|(arg1|func))...) 就是倒序柯里化也不能解决括号问题如果具有主从参进行数据变换的话可能 lodash 那样的点链会更好,但 _.intersection 难受了我半天。
    而且强迫症感到难受:到底求交集的时候哪个在前?
    所以什么时候有图形化 dataflow graph 编程?
    inhzus
        24
    inhzus  
       2019-08-30 11:32:04 +08:00 via Android
    我大概遵循的规则是:一行代码中,嵌套调用尽量不超过两层,链式调用尽量分行写。
    炫技不炫技不重要,把代码写的即便没有注释也能轻松看懂就行了。
    guokeke
        25
    guokeke  
       2019-08-30 11:32:09 +08:00   ❤️ 3
    什么是"可读性"?可读性有啥什么标准吗?自己看不顺眼的代码就是可读性差吗?
    wysnylc
        26
    wysnylc  
       2019-08-30 11:34:34 +08:00
    @Heylion #21 SimpleDateFormat 存在并发问题不建议使用甚至禁用,没有说他的代码会有问题
    如果一个方法存在问题,那么在有代替品的情况下应当使用代替品
    时间的格式化 java8 有 LocalDateTime java8 之前可以用 apache-dateUtils dateFormatUtils
    所以 SimpleDateFormat 这种存在问题的类有必要使用?
    wsy190
        27
    wsy190  
    OP
       2019-08-30 11:35:03 +08:00
    @guokeke
    就是这个问题。。。
    我认为写一行可读性差,他认为写很多可读性差
    我也在想到底哪种方式写好呢,
    ccpp132
        28
    ccpp132  
       2019-08-30 11:36:19 +08:00
    第一个 case 写一行比较好。不拆开就觉得读起来困难的话可以多锻炼一下阅读代码的能力
    wsy190
        29
    wsy190  
    OP
       2019-08-30 11:39:18 +08:00
    @ccpp132 也不是说读起来困难吧,只不过是觉得不能一目了然。在改的时候还要从头读。
    不过这应该还是和读代码能力有关系的。
    wysnylc
        30
    wysnylc  
       2019-08-30 11:39:43 +08:00
    @no1xsyzy #23 比较长的链式嵌套确实存在阅读的困难,但是他这个链式写得一点都不多也不长还远远称不上"阅读困难"或者"语意不清"
    比如使用 Stream.of(1,2,3).map().filter().flatMap()..... 这种大段的链式调用也有解决方案 在每一个调用后换行写注释即可
    函数式编程核心就是纯粹的链式调用,其次是 builder,然而二者都是存在链式调用 所以链式调用没有任何问题
    你把链式调用去了换成其他代码一样存在阅读困难,本质上不是代码怎么写,而是写代码的人的问题
    loginbygoogle
        31
    loginbygoogle  
       2019-08-30 11:43:17 +08:00 via Android
    就像一坨屎
    PriestTomb
        32
    PriestTomb  
       2019-08-30 11:45:10 +08:00
    团队里的一个年龄较小的同事也是这种写法,链式一路到底。。
    可能是我还没习惯,看他的代码真的很吃力,决心了好几次,都没看完他的代码。。
    leafre
        33
    leafre  
       2019-08-30 11:45:30 +08:00
    你看不惯,关人家什么事?你有资格评价别人的代码?
    zifangsky
        34
    zifangsky  
       2019-08-30 11:47:12 +08:00
    @wysnylc #14 当做局部变量可以用,没有线程安全问题。
    hundan
        35
    hundan  
       2019-08-30 11:47:53 +08:00 via Android
    功能复杂的时候 最多拆成一屏能读完的 三十行左右
    KyonLi
        36
    KyonLi  
       2019-08-30 11:48:07 +08:00   ❤️ 1
    拆开就会需要起很多变量名,这可是最烧脑的事情
    dsg001
        37
    dsg001  
       2019-08-30 11:48:38 +08:00
    如果需要从两个人中裁掉一个,老板会认为裁掉谁比较好?

    之前在类似问题下看到的回复
    specita
        38
    specita  
       2019-08-30 11:50:03 +08:00
    我觉得两种写法都 OK 啊,可读性好不好,1、排版(链式分行) 2、链式的方法名称起得好不好
    链式写得好的处理逻辑一目了然,但是还是不要链得太长了.. builder 这种除钱
    MMMMMMMMMMMMMMMM
        39
    MMMMMMMMMMMMMMMM  
       2019-08-30 11:51:18 +08:00
    没问题啊,有注释就行了

    没注释你让他自己改去
    Jex
        40
    Jex  
       2019-08-30 11:51:24 +08:00   ❤️ 2
    菜鸡互啄
    wsy190
        41
    wsy190  
    OP
       2019-08-30 11:52:50 +08:00
    @leafre 又没说看不懂,团队协作提提意见怎么了?而且我也是抱着讨论的心思和他谈的
    再说了,我和别人讨论,关你什么事?你有资格评论我的帖子?
    STRRL
        42
    STRRL  
       2019-08-30 11:53:54 +08:00
    我在工作中喜欢用 chain 这种方式 稍微有些复杂的 try-catch 都会再写一个 private 方法装一下
    然后无论拆不拆开 可加 fianal 的变量记得加 final...
    vmskipper
        43
    vmskipper  
       2019-08-30 11:54:37 +08:00
    越复杂的东西,越要写的简单,越少的依赖
    SuperMild
        44
    SuperMild  
       2019-08-30 11:55:29 +08:00
    如果没有裁判,是很难分清是非对错的。比如这种,必须有一个组长之类的人,和大家讨论后制定一份代码风格手册,类似于 Google、阿里做的那些 Java 风格手册,这样有规矩才能分对错。

    不然的话谁都不服谁,两个地位相同的人讨论这种问题效率是很低的,你说的再有道理,但是他不服气呀,如果没有裁判,“道理”的力量很微弱。
    chanchan
        45
    chanchan  
       2019-08-30 11:57:44 +08:00
    除了 if else 省略花括号,变量声明在一行.别的我觉得没问题
    Sapp
        46
    Sapp  
       2019-08-30 11:57:44 +08:00   ❤️ 6
    链式调用要这么写

    ```

    xx
    .xxx() // 注释
    .xxx() // 注释
    .xxx(
    oo.xx()
    )
    .xxx(
    oo
    .xx()
    .xxx()
    )

    ```
    sonxzjw
        47
    sonxzjw  
       2019-08-30 11:58:29 +08:00
    你同事这样是一种变成风格,链式编程,有些语言哲学里很提倡例如 scala,确实阅读性不错。
    我一度也很喜欢这种做法,但后来发现 java 中(其他的未生产上丰富的现实经验,但差不多吧)这样写很难快速的定位问题。每一个链相当于都会有异常,这样几乎无法精确捕获并处理。

    所以后来我还是拆分开来写了,坑别人事小,坑自己事大,到最后有问题还是得分开来搞。
    jiezhi
        48
    jiezhi  
       2019-08-30 12:00:00 +08:00 via iPhone
    用 builder 会清爽很多吧
    passerbytiny
        49
    passerbytiny  
       2019-08-30 12:02:26 +08:00
    我本来想看看楼主说得是啥,然而我根本看不下去主题描述。

    只说一点,在不使用缩写、转义等替代描述的情况下,代码越少,可读性越高但可调整型(断点调试、后续追加代码)越低。“?:”三目描述符就是一个典型,可读性很高,但是当要调试,或者追加更多逻辑的时候,就不如“ if else ”方便。
    Sornets
        50
    Sornets  
       2019-08-30 12:05:22 +08:00
    当我觉得这个代码以后不会我来维护并且我心情比较差的时候,会写成你同事这种。

    其他情况,会写成你这种
    zzczzc
        51
    zzczzc  
       2019-08-30 12:12:16 +08:00
    我自己的话会喜欢用语法糖吧,工作还是尽量多考虑可读性好点
    karnaugh
        52
    karnaugh  
       2019-08-30 12:14:22 +08:00
    最近我也遇到类似的事情,我的思考结论是:
    两个角度,因为是自己写的代码,每个东西是用来干啥的都知道,所以缩写成一条感觉看着很干净。。。
    但是!!
    到别人看的时候简直就是死了🐴了,难懂的雅痞,过个半年一年的,他再回来看着一条代码,估计他也得看半天

    这种“我觉得”的负优化经常会有,只是因为自己的角度限制了思维,你可以自己写几个这样的代码让他看,他大概就知道自己写的这个代码有多屎了
    izoabr
        53
    izoabr  
       2019-08-30 12:26:40 +08:00
    用过 Python 的觉得这些都是乱码,太乱太复杂了
    c0011
        54
    c0011  
       2019-08-30 12:30:11 +08:00
    我看你的你同事的代码头疼。
    pjzhong
        55
    pjzhong  
       2019-08-30 12:34:12 +08:00
    现在除了技术隔阂,还有风格隔阂了?
    tudouxiong
        56
    tudouxiong  
       2019-08-30 12:34:43 +08:00 via Android
    @leafre 感谢 block
    jason19659
        57
    jason19659  
       2019-08-30 12:37:05 +08:00
    设置为当日零点 dto.setStartTime(dto.getStartTime()+" 00:00:00"); 这么写真的没问题吗。。。万一时区不一样。。
    blackmirror
        58
    blackmirror  
       2019-08-30 12:37:18 +08:00
    这代码粘得看得我头痛
    WuMingyu
        59
    WuMingyu  
       2019-08-30 12:40:52 +08:00 via iPhone
    链式的分行写 可以不
    Tink
        60
    Tink  
       2019-08-30 12:41:35 +08:00 via iPhone
    能写到一行并且出现问题能够很轻易判断问题在哪的程序员很厉害
    insaneguy
        61
    insaneguy  
       2019-08-30 12:42:22 +08:00
    强推代码规范检查可解:确定规范,强制执行。
    pain400
        62
    pain400  
       2019-08-30 12:43:34 +08:00
    @wysnylc 因为线程不安全,所以非多线程环境也不用吗。。。
    vkhsyj
        63
    vkhsyj  
       2019-08-30 12:48:45 +08:00
    链式调用太长必须分行,不然可读性太低了
    susecjh
        64
    susecjh  
       2019-08-30 12:48:47 +08:00
    又不是搞 acm,搞那么精简干啥
    good1uck
        65
    good1uck  
       2019-08-30 12:50:15 +08:00 via Android
    小作坊..风格多
    kkeiko
        66
    kkeiko  
       2019-08-30 12:58:26 +08:00
    链式调用写法没问题,大部分情况下就是代码越少越好。说可读性差的只是个人问题。
    OHyn
        67
    OHyn  
       2019-08-30 13:02:37 +08:00
    写的时候考虑一下过几个月自己是否看得懂就好了。。
    Beeethoven
        68
    Beeethoven  
       2019-08-30 13:07:26 +08:00
    我写这种 SETGET 链经常出 NPE.. 后来再也不这么写了
    gkiwi
        69
    gkiwi  
       2019-08-30 13:12:55 +08:00
    写代码的时候都会走这个阶段,避免不了:

    刚开始:拼拼凑凑能跑就行
    然后:以代码量少为大佬的一个标准,并且努力执行(嗯,我也有段时间痴迷各种一行代码实现,没错,说的就是 python )
    之后:逻辑易读的代码,适量备注
    之后:易于单测的易读代码(目前我大概是这个阶段)

    再之后的还需要体会~~
    luopengfei14
        70
    luopengfei14  
       2019-08-30 13:21:12 +08:00
    @wsy190 突然感觉我好老。。。
    zhuweiyou
        71
    zhuweiyou  
       2019-08-30 13:38:49 +08:00   ❤️ 1
    个人的原则是 能写一行 坚决不写两行
    JiafuYuan
        72
    JiafuYuan  
       2019-08-30 13:41:15 +08:00
    这样写会有无数 bug 吧,各种异常都没考虑
    yiyi11
        73
    yiyi11  
       2019-08-30 13:41:32 +08:00 via Android   ❤️ 1
    看情况的,很多东西没有绝对的对错,核心是以人(可读性)为本,多沟通,达成共识。比如 new().set()的用法,团队可以做一个规范,1.强制要求先 new,后 set。2.或者统一使用带参构造函数。3.或者不超过 1 个属性的时候可以使用连写的写法(因为较少属性的时候依然可以保持较高的可读性,不必排斥简短的写法),否则使用 1 或 2 的写法。
    lighter
        74
    lighter  
       2019-08-30 13:43:29 +08:00
    可读和简洁之间,更喜欢可读性。
    Aumujun
        75
    Aumujun  
       2019-08-30 13:44:36 +08:00
    看 github 上的开源项目,代码基本都很精简。。 我个人认为精简是一种好习惯
    xuyaomin
        76
    xuyaomin  
       2019-08-30 13:45:57 +08:00
    这个应该不能算是炫技
    DingSoung
        77
    DingSoung  
       2019-08-30 13:46:07 +08:00 via iPhone
    自己技术不行看不懂别人的代码,说别人代码可读性差。😂
    yiyi11
        78
    yiyi11  
       2019-08-30 13:46:17 +08:00 via Android
    @karnaugh 对,很多情况下都是“专家盲点”,一个人掌握了某些事物以后,就忘记了当初自己一窍不通的感觉。
    Jrue0011
        79
    Jrue0011  
       2019-08-30 13:48:23 +08:00
    看情况,方法返回值没有重用的话就写一起,有重用的话就声明一个变量接收,太长的话也可以适当写成多行,但方法链一般会把每个 . 都换行
    pb941129
        80
    pb941129  
       2019-08-30 13:49:09 +08:00
    一般 Python 我的原则是 性能和可读性至上
    如果这个链式语句大量用到了某一个同一个中间函数或者需要反复计算一个中间数值
    那就把这个中间函数提取出来单独计算成变量再进行链式语句的书写
    如果没有 那我觉得持续用.来嵌套方法是没有什么问题的 尤其是一些很基本的方法 你知道这个方法的输入和输出大概是什么 如果这都要担心会不会翻车 或者没有把握 那 emmm
    能少用变量名称就少用变量名称 我宁愿看一个长链式的语句也不愿意去猜你的那些个没有意义 用过了就扔了 中间变量乱七八糟的命名代表什么意思 我甚至还要费劲心思去考虑这段代码的关键变量和不重要的变量是什么 在这一点上 长链式读起来就很舒服 一下子就能知道你是怎么实现以及背后的算法逻辑是什么
    的确拆开来写很稳 但是太稳了就是代码给人一种 nerd 的感觉...
    v2qwsdcv
        81
    v2qwsdcv  
       2019-08-30 13:50:45 +08:00
    笑死我了,您怕是别用 java8 的 steam 了。
    ThomasZ
        82
    ThomasZ  
       2019-08-30 13:51:19 +08:00 via Android
    又不是再搞那个最短代码比赛,这样写没有可读性,没有可调试性,单纯炫技不好
    519718366
        83
    519718366  
       2019-08-30 13:51:35 +08:00
    他这一行,到时候 npe 了,天知道是哪个对象 null 了....亲生感受
    他要是牛逼,敢保证不会 npe,那你能怎么办,忍着呗,出了 bug,不要给你查就行
    yiyi11
        84
    yiyi11  
       2019-08-30 13:52:18 +08:00 via Android   ❤️ 1
    个人倾向链式分行,我是分行狂魔,看到链式调用哪怕只有 2 个很短的函数连着都要每个点起一行,而且点必须对齐。
    yiyi11
        85
    yiyi11  
       2019-08-30 13:53:31 +08:00 via Android
    sql 同理,只有 2 个字段的语句也必须一行一个字段。
    STRRL
        86
    STRRL  
       2019-08-30 13:54:10 +08:00
    大家说到 NPE 的问题,建议使用 JSR 305 中提到的 @NonNul l 和 @CheckForNull 解决
    iblessyou
        87
    iblessyou  
       2019-08-30 13:55:55 +08:00
    看了一遍还没人从这个角度提过:

    某些公司有代码统计的,这时注释和换行都能给你加代码量,你的写法可以加分。。。
    zkqiang
        88
    zkqiang  
       2019-08-30 14:00:29 +08:00   ❤️ 1
    虽然为了精简,嵌套太多,确实不容易看懂
    但是一味的追求所谓“可读性”,反而导致代码冗长,一排重复的变量名,那不又是另一个极端?
    xpfd
        89
    xpfd  
       2019-08-30 14:01:13 +08:00
    一年后让他再看这段代码 他会骂 这哪个傻逼写的 就不能写的简单点吗? 非要转那么多弯
    Rwing
        90
    Rwing  
       2019-08-30 14:05:09 +08:00   ❤️ 1
    ```
    public OutVoGlobal list(BatteryOrderDTO dto, UserInfo user) {

    var outVoGlobal=new OutVoGlobal(EnumRetCode.SUCCESS);
    var sdf = new SimpleDateFormat("yyyy-MM-dd");
    if(!StringUtils.isEmpty(dto.StartTime)){
    try {
    sdf.parse(dto.StartTime);
    dto.StartTime = dto.StartTime+" 00:00:00";
    } catch (ParseException e) {
    dto.StartTime = "";
    }
    }
    if(!StringUtils.isEmpty(dto.EndTime)){
    try {
    sdf.parse(dto.EndTime);
    dto.EndTime = dto.EndTime+" 23:59:59";
    } catch (ParseException e) {
    dto.EndTime = "";
    }
    }
    dto.Belong = user.UserNo;
    PageHelper.startPage(dto.PageNo, dto.PageSize);
    List<BatteryOrder> list = orderMapper.list(dto);
    outVoGlobal.Data = list;
    return outVoGlobal;

    }
    ```

    有没有舒服点?
    blindie
        91
    blindie  
       2019-08-30 14:10:27 +08:00
    链式调用这么长不点号对齐写锤子啊,分分钟某个节点看漏
    Aixtuz
        92
    Aixtuz  
       2019-08-30 14:16:12 +08:00
    凡事有度,过犹不及。
    Takamine
        93
    Takamine  
       2019-08-30 14:35:45 +08:00
    只要是过了 code review 的,说明是符合团队风格的代码,不要慌。:doge:
    broadliyn
        94
    broadliyn  
       2019-08-30 14:37:25 +08:00
    @wysnylc
    这里的 SimpleDateFormat 并没有竞态问题,为什么不能用??
    阿里规范是让你不要在线程不安全的情况下使用 SDF,而不是让你在并发环境下不要用 SDF。
    你也是半桶水。
    BigDogWang
        95
    BigDogWang  
       2019-08-30 14:38:50 +08:00
    你们都在这扯个啥,这不是链式不链式的问题,这是链式套链式啊,看的人恶心
    whp1473
        96
    whp1473  
       2019-08-30 14:46:54 +08:00   ❤️ 3
    一、不赞同
    1.String openid = (String) tokenMap.get("openid"),userMapKey;❌
    2.省略{} if、else 不分行❌
    二、争议
    return new OutVoGlobal(EnumRetCode.SUCCESS).setData(orderMapper.list(dto.setBelong(user.getUserNo()))); ❌
    这种类似风格,写的好很推崇,但写的差很容易写出屎一样的代码。我见过有 100 多行的链式,你读到后面就忘了前面,后来那个写的人也不知道了,哈哈。我觉得原则上支持链式,但是你要拆分的力度适中,5 个左右不超过 10 并且语义明了。
    Java 中流式写法更适合数据处理。常用的实例:
    widgets.stream()
    .filter(b -> b.getColor() == RED)
    .sorted((x,y) -> x.getWeight() - y.getWeight())
    .mapToInt(Widget::getWeight)
    .summaryStatistics();
    或者
    numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
    你可以看到数据从第一行,到最后一行语义就是逻辑,是由顺序的。
    三、分析
    return new OutVoGlobal(EnumRetCode.SUCCESS).setData(orderMapper.list(dto.setBelong(user.getUserNo())));
    写的问题在哪里,我们分析一下:
    执行顺序:创建 OutVoGlobal 返回值——>setData 设置数据——>orderMapper.list 执行——>dto.setBelong 封装 userNo,同时要获取 userNo
    在我们眼里的顺序是怎样的,获取 userNo ——>封装——>执行 list ——>封装返回 OutVoGlobal。可以看出它实际上需要逆着思维的顺序,user.getUserNo()这部分如果嵌套过多甚至你需要不断找。所以这种风格有点像用但是没用好的感觉。
    四、改造
    OrderParamBuilder.Builder().setUserNo(user.getUserNo()).build().list(orderMapper).ifNull(EnumRetCode.ERROR).else(EnumRetCode.SUCCESS);
    或者
    orderMapper.list(OrderParamBuilder.Builder().setUserNo(user.getUserNo()).build()).****
    rainymorn
        97
    rainymorn  
       2019-08-30 14:54:35 +08:00
    不喜欢分行,能写到一行的绝不写到多行
    多行不利于阅读
    freebird1994
        98
    freebird1994  
       2019-08-30 14:56:02 +08:00
    链式不链式是一回事。入参不做校验么?一堆异常不给你抛?还是在 controller 层做了校验呢?
    其实现在的 java 代码风格越来越偏向链式编程了。我也喜欢用
    wsy190
        99
    wsy190  
    OP
       2019-08-30 14:58:00 +08:00
    @freebird1994 确实是,controller 层做了 try catch..
    wsy190
        100
    wsy190  
    OP
       2019-08-30 14:59:24 +08:00
    @whp1473 非常感谢,受益匪浅。
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1190 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 18:31 · PVG 02:31 · LAX 10:31 · JFK 13:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.