【不靠谱程序员】你String用得真6

137 阅读5分钟

一个service类里封装了一个生成随机数的方法:getRandom

/**
 * 获取随机数
 *
 * @param min
 * @param max
 * @return
 */
private static String getRandom(int min, int max) {
    Random random = new Random();
    int s = random.nextInt(max) % (max - min + 1) + min;
    return String.valueOf(s);

}

我们来看看这个service类里相关调用的地方 ①下面的使用有多处

Date date = getBeforeSecondDate(orderEndTime, -1 * Integer.valueOf(getRandom(0, 60)));

②下面的使用有一处

String hours = getRandom(11, 18);
String min = getRandom(15, 59);
String second = getRandom(10, 59);
orderEndTime = orderEndTime + " " + hours + ":" + min + ":" + second;//格式:yyyy-MM-dd HH:mm:ss

不靠谱!

既然如此,你就不能让getRandom返回int吗?类型转来转去的,不无聊吗?

——————————————————————————————————

关于好代码的定义,各路大神都给出了自己的定义和见解

  • 整洁的代码如同优美的散文。—— Grady Booch
  • 任何一个傻瓜都能写出计算机可以理解的代码。唯有写出人类容易理解的代码,才是优秀的程序员。—— Martin Fowler

首先要达成一致,我们写的代码,除了用于机器执行产生我们预期的效果之外,更多的时候是给人读的。那么,** ↓↓↓↓程序设计,你用心了吗?↓↓↓**

需求直译

§ 字段定义

需求原型上,查询结果列表里有一列叫“删除状态”。程序员设计的表里与之对应定义了一个状态:delete_status varchar(16) 'NORMAL-未删除,DELETED-已删除'。

其实,当一个变量仅在两个值之间发生变动时,可以简化为是/否、0/1、Y/N这样的表示形式,我们的应用系统将会更美。本例可以是,deleted char(1) 'Y/N',或者delete_flag tinyint '1/0'。

 

学生管理列表 需求原型上有一列的列名叫“所属班级”,开发人员设计学生表结构时,就定义了一个字段:belonging_class_id。(班级表:class,主键:class_id)
设计方面要抓本质:这个字段名直接改成 class_id 就行了。
不要被这种“所属”字样迷惑,这是产品经理对用户体验方面的展示。否则,如果原型上叫“所在班级”,难道还要把字段名定义成“in_class_id"吗?

 

 

§ 程序设计

在一些涉及到规则配置的需求里,例如客户付款通道配置,既要支持按商户配置,又要支持为所有商户来一个默认配置。

我们程序怎么实现呢?

不用创建两个配置表,一个配置表就行了。表里的客户id字段,对于特定商户,那就是这个商户的id;对于所有商户,存一个约定的标记(例如:0或空串)就行了。

 

§ 产品经理说归说,我们得站在技术专业的角度来实现

客户系统里,有一个功能是,客户通过upload控件上传资质文件图片,文件控制在5M以内。技术层面,前端以文件流的方式调用后端接口,将文件上传到服务器,然后返回文件访问url,前端根据url展示缩略图。在测试阶段发现,当图片过大或网络慢时,会出现上传完的图片无法显示。产品经理要求图片必须正常显示,保证客户体验。结果,前端同学使用了轮询的方式,即在超时时间内没有返回url,则走超时重试。

恰好,某次生产事故,就因为这个“死循环”导致服务器网络带宽几乎耗尽,而影响了系统的正常使用。

后续的解决方案:延长超时时间为10s,为超时重试设定次数限制。

见怪不怪的(bú qià dàng de)用户提示

§ 谁是管理员?

一出现问题,系统动辄提示“系统错误,请联系管理员”、“系统异常,请重试”。

这时候,客户就会反馈给运营,运营自然也不晓得啥原因,最终这个皮球就传到技术手里了。程序员一顿排查猛如虎,原来,是某个字段的值非法。

§ 您的操作非法

用户登录到系统里,一如往常地使用着系统,突然,页面上提示“您的操作非法”。还犯法了??你说用户会不会感到惶恐~

§ 无独有偶

不当的提示满天飞。

浏览器与服务器出现网络异常,结果提示的却是业务错误。我遇到的一个经历,企业客户正在通过我们的客户门户上传结算批次,发现提示“结算批次有误,请核实!”。程序员后来排查的结论是,前端ajax请求的error里竟然提示了这个信息。

有容乃大

§ 家常便饭的NPE

程序做一下判空吧。

if (null == obj)

if(Objects.isNull(obj))

if (StringUtils.isEmpty(str))

if(CollectionUtils.isEmpty(list))

同样对于equals,常量放前边。或者改用java.util.Objects#equals

 

§ 空格

接收到的文本数据,有必要做一下判空处理。

再细致一些,比如身份证号码、银行卡号、手机号、企业信用代码,可以把这些文本中间的空格给去掉,这样,后续的要素认证等使用的地方会一马平川毫无障碍。

类似的,再比如全角字符与半角字符,例如:“阿里巴巴(中国)”与“阿里巴巴(中国)”,当这些文本作为查询条件的时候,系统如果可以兼容,也许会更好!

偷懒的话,你会忙不迭地应付处理类似的运营问题。

偷懒的话,在某些情况下,你的代码就会遭到脏话伺候。

臭代码是怎么形成的?

§ 需求迭代

如下代码

    ...
    }else {
        try {
            String s = new BigDecimal(deliverAmt).setScale(2, BigDecimal.ROUND_HALF_DOWN).toString();
            designDeliverImportDTO.setDeliverAmt(s);
        }catch (Exception e){
            errMsg.append("结算金额填写规则有误");
            flag = true;
        }
    ...

 

新需求来了,说得验证金额必须大于0才行。然后,代码变成了下面这样:

    ...
    }else {
        try {
            String s = new BigDecimal(deliverAmt).setScale(2, BigDecimal.ROUND_HALF_DOWN).toString();
            if (Double.valueOf(s) < 0){
                errMsg.append("结算金额不能为负数");
                continue ;
            }
            designDeliverImportDTO.setDeliverAmt(s);
        }catch (Exception e){
            errMsg.append("结算金额填写规则有误");
            flag = true;
        }
    ...