关于java:高效能团队的Java研发规范进阶版

39次阅读

共计 3631 个字符,预计需要花费 10 分钟才能阅读完成。

目前大部分团队是应用的阿里巴巴 Java 开发标准,不过在日常开发中不免遇到笼罩不到的场景,本文在阿里巴巴 Java 开发标准根底上,补充一些罕用的标准,用于晋升代码品质及加强代码可读性。

编程规约

1、根底类型及操作

(1)转换

根本类型转换

String 类型转数字:应用 apache common-lang3 包中的工具类 NumberUtils,劣势:可设置默认值,转换出错时返回默认值

NumberUtils.toInt("1");

拆箱:包装类转化为根本类型的时候,须要断定 null,比方:

Integer numObject = param.get(0);
int num = numObject != null ? numObject : 0;
对象类型转换

应用 MapStruct 工具,转换类后缀 Convertor,所有转换操作都在转换类中操作,禁止在业务代码中编写大量 set 代码。

(2)判断

枚举断定

应用枚举判等,而非枚举对应的数字。因为枚举更直观,不便查看代码及调试,数字容易出错。

判空

各种对象的判空:

// 对象判空 & 非空
Objects.isNull()
Objects.nonNull()

//String 判空 & 非空
StringUtils.isEmpty()   // 可匹配 null 和空字符串
StringUtils.isNotEmpty()
StringUtils.isBlank()   // 可匹配 null、空字符串、多个空白字符
StringUtils.isNotBlank()

// 汇合判空 & 非空
CollectionUtils.isEmpty()
CollectionUtils.isNotEmpty()

//Map 判空 & 非空
MapUtils.isEmpty()
MapUtils.isNotEmpty()
断言

应用 Guava 里的 Preconditions 工具类,比方:

// 如果是空则抛异样
Preconditions.checkNotNull()
// 通用判断
Preconditions.checkArgument()

2、汇合解决

(1)Map 快捷操作

举荐:

// 如果值不存在则计算
map.computeIfAbsent("key",k-> execValue(k));
// 默认值
map.getOrDefault("key", DEFAULT_VALUE)

反例:

// 如果值不存在则计算
String v = map.get("key");
if(v == null){v = execValue("key");
    map.put("key", v);
}
// 默认值
map.containsKey("key") ? map.get("key") : DEFAULT_VALUE

(2)创建对象

构造方法或 Builder 模式,超过 3 个参数对象创立应用 Builder 模式

//Java11+:
List.of(1, 2, 3)  
Set.of(1, 2, 3)
Map.of("a", 1)

//Java8 中不可变汇合(需引入 Guava)ImmutableList.of(1,2,3)
ImmutableSet.of(1,2,3)
ImmutableMap.of("key","value")
// 多值状况
ImmutableMap.builder()
    .put("key", "value")
    .put("key2", "value2")
    .build()

//Java8 中可变汇合(需引入 Guava)Lists.newArrayList(1, 2, 3)
Sets.newHashSet(1, 2, 3)
Maps.newHashMap("key", "value")

反例:

new ArrayList<>(){{add(1);
   add(2);
}};

(3)汇合嵌套

汇合里的值如果是根底类型必须加上正文,阐明汇合里存的是什么,比方:

// 返回值: Map(key: 姓名, value: List( 商品))
Map<String, List<String>> res;

超过 2 层汇合对象封装必须封装成自定义类:

// 举荐
Map<String, List<Node>> res;

@Value
public static class Node {
    /**
    * 备注阐明字段
    */
    String name;
    /**
    * 备注阐明字段 2
    */
    List<Integer> subjectIds;
}

// 反例
Map<String, List<Pair<String, List<Integer>>>> res;

异样及日志

1、异样

对于异样及错误码的思考,请参考笔者的另一篇文章:错误码设计思考

异样除了抛异样还有一种场景,即:下层发动多个必要调用,某些可能失败,须要下层自行决定解决策略,举荐应用 vavr 中的 Either 类,Either 应用倡议:通常咱们应用左值示意异样,而右值示意失常调用后的返回后果,即: Either<Throwable, Data>

2、日志

(1)日志文件

依据日志等级个别分为 4 个日志文件即可:debug.log、info.log、warn.log、error.log;

如有非凡需要可依据场景独自建文件,比方申请日志:request.log、gc 日志:gc.log 等。

(2)所有用户日志都要有追踪字段

追踪字段包含:traceId、userId 等,举荐应用 MDC,罕用的日志框架:Log4j、Logback 都反对。

(3)日志清理及长久化

本地日志依据磁盘大小,必须设置日志保留天数,否则有硬盘满危险;

分布式环境为了不便查问,须要将日志采集到 ES 中查问;

重要日志:比方审计日志、B 端操作日志须要长久保留,个别是保留到 Hive 中;

工具篇

1、JSON

举荐:应用 Gson 或 Jackson;

不举荐:Fastjson。Fastjson 爆出的破绽多。

2、对象转换

举荐:MapStruct,依据注解编译成 Java 代码,没有反射,速度快;行为可预测,可查看编译后的 Java 代码查看转换逻辑;

不举荐:BeanUtils、Dozer 等。须要反射,行为不可预测,须要测试;

不举荐:超过 3 个字段手动转换;

3、模板代码

举荐:Lombok,缩小代码行数,晋升开发效率,主动生成 Java 代码,没有性能损耗;

不举荐:手动生成大量 set、get 办法;

4、参数校验

举荐:hibernate Validation、spring-boot-starter-validation,可通过注解主动实现参数拦挡;

不举荐:每个入口(比方 Controller)都 copy 大量反复的校验逻辑;

5、缓存

举荐:Spring Cache,通过注解管制缓存逻辑,适宜罕用的加缓存场景。

设计篇

1、正向语义

正向语义的益处在于使代码容易了解。比方:if(judge()){….},很容易了解,即:断定胜利则执行代码块。

相同,如果是负向语义,思维还要转换一下,个别用于办法前置的参数校验。

正向语义的利用场景有:

  • 办法定义:办法名举荐:canPass、checkParam,返回 true 代表胜利。不举荐:比方 isInvalidParam 返回 true 代表失败,减少了解老本;
  • Lambda 表达式:filter 操作符中返回 true 是能够通过的元素;
  • if 和三目运算符:condition ? doSomething() : doSomething2() , 条件断定后紧跟的是断定胜利后执行的操作。

反例:

if (!judge()) {doSomething2()
} else {doSomething()
}

2、进攻式编程

(1)内部数据校验

内部传过来数据都须要校验,个别分为两类:

  • 数据流入:用户 Http 申请、RPC 申请、MQ 消费者等
  • 数据依赖:依赖的第三方 RPC、数据库等

如果是数据流入,肯定要首先校验数据合法性再往下执行,举荐 hibernate Validation 这类工具,能够很不便的做数据校验

数据是数据依赖,肯定要思考各种网络、限流、背压等场景,做好熔断、降级保障。举荐建设防腐层,将第三方的限界上下文语义转换为以后上下文语义,防止了解上的歧义;

(2)Null 解决

  • 对于强依赖,没有返回值不行(比方查询数据库):间接抛异样;
  • 须要反馈给下层解决:

    (1)可能返回 null 的场景:应用 Optional;

    (2)下层须要感知信息异样信息:应用 vavr 中的 Either;

  • 可降级:

    (1)返回值是默认值:汇合类返回,数字返回 0 或 -1,字符串返回空字符串,其余场景自定义

    汇合默认值:

Collections.emptyList()  // 空 List
Collections.emptySet()   // 空 Set
Collections.emptyMap()   // 空 Map

总结

本文总结了 Java 开发罕用的高级标准,临时想到这么多,对文章中观点感兴趣,欢送留言或加微信交换。

作者博客链接:Java 研发标准 (进阶版)

作者简介:木小丰,美团 Java 技术专家,专一分享软件研发实际、架构思考。欢送关注公共号:Java 研发

更多精彩文章:

错误码设计思考

Java 线程池进阶

从 MVC 到 DDD 的架构演进

平台化建设思路浅谈

构建可回滚的利用及上线 checklist 实际

正文完
 0