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

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

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

19672 次点击
所在节点    程序员
149 条回复
insaneguy
2019-08-30 12:42:22 +08:00
强推代码规范检查可解:确定规范,强制执行。
pain400
2019-08-30 12:43:34 +08:00
@wysnylc 因为线程不安全,所以非多线程环境也不用吗。。。
vkhsyj
2019-08-30 12:48:45 +08:00
链式调用太长必须分行,不然可读性太低了
susecjh
2019-08-30 12:48:47 +08:00
又不是搞 acm,搞那么精简干啥
good1uck
2019-08-30 12:50:15 +08:00
小作坊..风格多
kkeiko
2019-08-30 12:58:26 +08:00
链式调用写法没问题,大部分情况下就是代码越少越好。说可读性差的只是个人问题。
OHyn
2019-08-30 13:02:37 +08:00
写的时候考虑一下过几个月自己是否看得懂就好了。。
Beeethoven
2019-08-30 13:07:26 +08:00
我写这种 SETGET 链经常出 NPE.. 后来再也不这么写了
gkiwi
2019-08-30 13:12:55 +08:00
写代码的时候都会走这个阶段,避免不了:

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

再之后的还需要体会~~
luopengfei14
2019-08-30 13:21:12 +08:00
@wsy190 突然感觉我好老。。。
zhuweiyou
2019-08-30 13:38:49 +08:00
个人的原则是 能写一行 坚决不写两行
JiafuYuan
2019-08-30 13:41:15 +08:00
这样写会有无数 bug 吧,各种异常都没考虑
yiyi11
2019-08-30 13:41:32 +08:00
看情况的,很多东西没有绝对的对错,核心是以人(可读性)为本,多沟通,达成共识。比如 new().set()的用法,团队可以做一个规范,1.强制要求先 new,后 set。2.或者统一使用带参构造函数。3.或者不超过 1 个属性的时候可以使用连写的写法(因为较少属性的时候依然可以保持较高的可读性,不必排斥简短的写法),否则使用 1 或 2 的写法。
lighter
2019-08-30 13:43:29 +08:00
可读和简洁之间,更喜欢可读性。
Aumujun
2019-08-30 13:44:36 +08:00
看 github 上的开源项目,代码基本都很精简。。 我个人认为精简是一种好习惯
xuyaomin
2019-08-30 13:45:57 +08:00
这个应该不能算是炫技
DingSoung
2019-08-30 13:46:07 +08:00
自己技术不行看不懂别人的代码,说别人代码可读性差。😂
yiyi11
2019-08-30 13:46:17 +08:00
@karnaugh 对,很多情况下都是“专家盲点”,一个人掌握了某些事物以后,就忘记了当初自己一窍不通的感觉。
Jrue0011
2019-08-30 13:48:23 +08:00
看情况,方法返回值没有重用的话就写一起,有重用的话就声明一个变量接收,太长的话也可以适当写成多行,但方法链一般会把每个 . 都换行
pb941129
2019-08-30 13:49:09 +08:00
一般 Python 我的原则是 性能和可读性至上
如果这个链式语句大量用到了某一个同一个中间函数或者需要反复计算一个中间数值
那就把这个中间函数提取出来单独计算成变量再进行链式语句的书写
如果没有 那我觉得持续用.来嵌套方法是没有什么问题的 尤其是一些很基本的方法 你知道这个方法的输入和输出大概是什么 如果这都要担心会不会翻车 或者没有把握 那 emmm
能少用变量名称就少用变量名称 我宁愿看一个长链式的语句也不愿意去猜你的那些个没有意义 用过了就扔了 中间变量乱七八糟的命名代表什么意思 我甚至还要费劲心思去考虑这段代码的关键变量和不重要的变量是什么 在这一点上 长链式读起来就很舒服 一下子就能知道你是怎么实现以及背后的算法逻辑是什么
的确拆开来写很稳 但是太稳了就是代码给人一种 nerd 的感觉...

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

https://tanronggui.xyz/t/596413

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

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

© 2021 V2EX