{{:pasted:20160310-213710.png}} ===== 函数 ===== ---- 约定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时,使用信任模式 -> 还能有什么地方会出现空指针???