用户工具


空值处理

  • 不合法的对象实例化应该失败
  • 校验集合中的数据是否为null
  • 可能返回空的对象一定要用Optional封装
    • 映射操作,返回值一定是Optional类型
      • map操作
      • 数据库操作
    • 转换操作,返回值可能是Optional类型
      • 字符串转成驼峰(不是Optional类型)
      • 按逗号分割字符串,返回第二个字符串(是Optional类型)
    • 但凡有一定业务逻辑的数据,都要用对象包装起来,这样可以在创建的时候验证数据是否合法
      • 如:需要各种维度拼接成数据库的key。就可以创建一个类DBKey将拼装key的过程封装起来

错误数据的定义

  • null,null虽然不是错误,但会导致各种错误
  • 不符合业务规则的数据

消灭错误数据

  • 阻止错误数据产生(在源头扼杀错误)
    • 一个简单数据,要么一定有值(如 String),要么可能为空(Optional<String>)
      • 注意,List,Map中也不能出现null,建议使用guava中的集合(不允许出现null元素)
      • 外部函数的返回值,用Optional封装
      • 对于需要序列化而无法定义成Optional类的对象,设置getXxx()的返回值为Optional类型
    • 一个复杂数据,在实例化时,必须判断是否满足业务规则。否则实例化失败
  • 阻止错误蔓延
    • 调用方绝不传递错误参数
      • 严格遵守函数的参数约定(参数,返回值就是【契约】,调用方必须要遵守)
    • 被调用方绝不返回错误数据
      • 如果无法计算,则抛出异常
        • 一定是传参不对,只有调用方才知道怎么处理

最终每个对象、每个函数都是可信任的。数据、对象在创建的时候保证合法,就无需每次使用前都判断一次了。世界清静了

参数约定

参数约定越严格越好,并且被调用函数需要尽量考虑到每种情况(如:List类型中的元素是否允许为空)

id: 没有任何修饰,默认一定不为空
type: Optional修饰,可能为null
value: 必须不为空,且里面不允许存在空元素。 (语言层面无法限制,推荐用注解说明,函数注释说明也可以)
返回值:Optional修饰,可能为null

public Optional<Integer> fun(Integer id,
                            Optional<Integer> type,
                            @AllNoneNull List<Integer> value) {

}