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

2019-08-30 09:36:07 +08:00
 wsy190

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

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);

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

20357 次点击
所在节点    程序员
149 条回复
ColoThor
2019-08-30 15:09:27 +08:00
我有一个疑惑,时间为什么要用字符串表示
wxl1380610
2019-08-30 15:19:42 +08:00
请加空格
diferent
2019-08-30 15:24:37 +08:00
写好方法功能的注释,有对应的测试用例就行了.
作为外部调用者难道需要关心内部的实现?
Apache 那么多开源项目,用哪个也不需要一步步把源码看清楚啊.
CSEnter
2019-08-30 15:56:15 +08:00
想我这种初学者,看到这么精简的代码,感觉打开了一扇大门,看起来很舒服,当然也要写好注释。
yangzhezjgs
2019-08-30 15:57:16 +08:00
如果后期要改需求,这种代码改起来会爆炸
alextang95
2019-08-30 16:05:29 +08:00
链式没问题,分好行,相关注释写清楚就行。

分过行的代码,你改需求也只需要在对应的行中增加局部变量插入修改内容。

为了方便单步调试而制造一堆只在下一行使用的局部变量,看着就烦。尤其是变量名还起的不准确的情况下,这些局部变量名反而会影响对代码的理解,还不如一行注释。
leafre
2019-08-30 16:08:13 +08:00
@wsy190 评论你这种整天没事鸡蛋挑骨头的团队毒瘤,简直侮辱了我的流量
alextang95
2019-08-30 16:08:34 +08:00
return 过长,可能需要多增加一两个函数。
JDK 源码挺多 return 调用函数的,不过是分成了多层调用,如果精简写起来也和你同事写的差不多。
miniwade514
2019-08-30 16:10:53 +08:00
4 个括号套在一起,莫不是得到了前苏联火箭专家的真传?
wsy190
2019-08-30 16:25:28 +08:00
@leafre 整个帖子看下来就你阴阳怪气,我是昨天和人家当面讨论的,还鸡蛋里挑骨头?哪轮到你这小丑说话了?
回你侮辱我的智商,浪费我的时间,看你回帖瞎了我的眼睛,在这找存在感来了,也不想想老子为什么怼你
hexingb
2019-08-30 16:28:06 +08:00
链式调用没问题,但是也有点过度;并且变量写一行无法接受。炫技嫌疑很重。并且不是啥大不了的技术吧,一堆破逻辑。
wr410
2019-08-30 16:34:22 +08:00
如果只是纯调用,就是应该这么精简。

你觉得麻烦,说明是你的问题。

因为只是纯调用,没有任何逻辑,那么你调试的地方应该放在具体的方法里,而不是这里。
wsy190
2019-08-30 16:38:45 +08:00
@DingSoung 有的时候我也想呢。是不是真的是我太菜了?(昨天晚上突然想到这事,2 点多才睡。)
但是仔细想想我还是读的懂他的代码呢。就是读起来非常别扭。然后刚刚有人帮我指出我为什么别扭了。。


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()这部分如果嵌套过多甚至你需要不断找。所以这种风格有点像用但是没用好的感觉。
wsy190
2019-08-30 16:45:46 +08:00
@wr410 也不算是纯调用吧,因为写的是接口,好多参数在前端判断了之后我后台也会做一下判断,这段代码之所以让我改是因为前端传过来的时间是字符串类型,之后还可能传“开始时间”的中文,我需要对他重新做一下处理。所以让我来改这段代码。
如果按我的逻辑来讲的话 :
先给 dto 赋值,之后再拿着 dto 去查询数据库,最后将查到的数据赋值给 OutVoGlobal。我要是进行修改的话就应该改只在第一步加验证就行了。。但是他 dto 赋值是放在了方法的最后。。流程和我的惯性思维正好是相反的。
确实是在他的 return 之前加上我的代码就好了,但是我在没读他代码之前确实是不知道他是不是做了其他的操作,所以说我还是读了一遍他的代码。
uleh
2019-08-30 16:46:45 +08:00
哥,我觉得你应该试试新的 DateTime API
Ponze
2019-08-30 16:48:50 +08:00
嗯...想想 lambda kotlin
kkkkkrua
2019-08-30 17:03:21 +08:00
上面说链式的,真的确定这符合传统链式规范))))四个括号大丈夫?

````java

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

````


````java

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

````

如果是这种我觉得没毛病
zpf124
2019-08-30 17:04:59 +08:00
Java 代码的话 国内的风格还是比较古板,比较老的. 或者应该说大企业的风格都是这样的.
没有像国外那么多的那种财富自由的在野个人开发者, 而大企业的风格都是变化缓慢落后于当前时代的.

而你俩恰恰各自使用了接近其中某一种的方法.

老一点的风格 特点是没有歧义, 写的明确,但啰嗦, 比如链式都不怎么用.

//固执的老人: 写链式的都是异端, 这样多乱 我都快看不出来到底返回的是什么了, 看我写的多清晰!
// return new JBean().setName("xx");

JBean b = new JBean();
b.setName("xxx");
b.setAge(18);
return b;




新一点的风格 特点是方便清晰, 写起来能少些一些废话.

return new JBeanBuilder()
.setName("xxx");
.setAge(18)
.create();


而且好像不论哪种风格一般都不推荐把链式写一行.
guoyuchuan
2019-08-30 17:13:20 +08:00
可以尝试这样:
return new JBeanBuilder()
.setName("xxx");
.setAge(18)
.test(new XX().xx())
.create();
链式也是很好的一种写法,只是写到一行去了,可能可读性不好,但是不必去纠结这些;
ech0x
2019-08-30 17:19:26 +08:00
链式调用是链式调用的问题,我觉得链式调用挺好的简介好看。
点号不对其是代码格式化的问题,这个需要团队统一一个代码风格,如果没有统一的代码风格你没法责怪别人。
还有代码量越少越不容易出 Bug,也越容易找到 Bug,写好注释就行了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/596413

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX