用户工具


函数


约定0:函数内变量初始化成默认值,或者只定义不初始化。避免初始化成null。(整个程序中都应该尽量避免出现null)

约定1:函数依赖的参数类型始终和函数逻辑功能相关

  • 假设有个函数叫formatName(String name)
    • 这里传递String类型就可以,因为name就是String类型
  • 假设有个函数叫formatMyObjectName(MyObjec myObject)
    • 这里必须传递MyObject类型的对象,即使该函数只依赖 MyObject中的String name字段
    • 因为函数会扩展,可能随时会改变需求使这个函数依赖MyObject中其他字段

约定2:保证函数的事务性,要么成功执行,要么抛出异常

  • 参数合法行判断
    • 如果函数没有副作用:没有必要判断每个参数是否为null,因为参数如果不合法的话会在运行过程中抛出运行时异常
    • 函数有副作用:一定要保证参数合法,否则抛出异常
      • 一定要保证fast fail
      • 判断合法性时可以广泛使用assertEqual()等函数(因为assert函数特别简洁
        • 需要注意的地方:assertEqual等函数抛出的是Error类型异常,所以捕获时需要注意一下。或者封装成运行时异常

约定3:对于函数中某些地方只可能出现某些固定值,使用断言确保没有意外(最好让把断言封装成返回RunTimeException,否则返回Error,不方便捕获)

约定4:每个函数必须保证自己能给出一个合法结果,出现任何问题,抛出运行时异常,让上层决定这次调用失败对他带来的影响

  • 函数永远不需要返回null值(如果每个能保证这一点,那传入的参数也几乎不会有null值,整个程序也不会有)
    • 要么返回合法值,要么抛出异常
    • 对于字符串可以返回 “”
    • 对于Collect类型的返回值,如果需要可以返回空集合类型
      • return Collections.emptyList();
      • return Collections.emptySet();
      • return Collections.emptyMap();
    • 如果使用别人的接口或第三方库,可以按照此约定自己再封装一层使之符合该约定

约定5:如果调用者明确知道某个语句出现错误也不会影响调用者继续执行,则捕获该错误让程序继续运行。

约定6:设置一个异常处理函数,这个函数用来处理所有抛出的运行时异常

  • 到这里才被捕获的异常,说明当前流程已经无法执行了,否则应该被约定5捕获
  • 如果程序中使用assertEqual等函数,则捕获异常时需要注意一下java异常

总结来说就是,函数保证拿到正确的信息,返回可靠的结果。中间抛出的异常由上层处理,上层能处理后继续执行就处理,否则再往上抛统一处理


(这个约定好像没有必要)约定4:尽量保证每个函数线性化,函数中任何一句代码,都必须终止该函数,抛出异常

  • 也就是说减少约定5出现次数,
  • 一般在聚合数据,聚合功能的函数中出现这种状况,有什么好的解决方案吗?

返回值(过期)

有2种模式

  • 信任模式:凡是当前函数返回出去的东西,一定是有效的,接收方无需额外判断。如果出错则抛出异常
    • 优点
      • 非法值影响最小化(所有的非法值在产生的时候就被捕获了)
      • 程序可读性强(紧凑的逻辑代码不会被异常判断截成一段一段)
  • 不信任模式:凡是接收到的东西,我都需要校验其是否合法

很显然信任模式可以让程序变的更加简洁高效,生活不也是这样吗?哈哈。所以建议自己负责的模块使用信任模式,调用别人的接口时使用非信任模式,毕竟你对写接口的人可能一无所知

遵守如下原则,绝对不会碰到空指针异常

  • 因为java类库不会有空指针
  • 调用别人的接口时,做异常判断
  • 自己coding时,使用信任模式 → 还能有什么地方会出现空指针???