美文网首页
防御式编程

防御式编程

作者: henry_g | 来源:发表于2018-05-13 14:10 被阅读33次

最近业余时间在阅读《代码大全》,阅读“防御式编程”章节的时候非常受启发,自己之前对系统的错误处理这块也确实随意了。

什么时候应该代码应该自己catch掉错误并且处理了,什么时候应该抛出给上层,抛到上层时候要如何处理,如何使用断言等等没有一套规范。所以这里总结下应该如何来做防御式编程。

什么是防御式编程

防御式编程是承认程序都会有问题,无论是自己写的模块,团队中其他人写的模块甚至第三方工具包。然后依据这个来指导写代码,子程序不应该因为传入的错误数据被破坏了。

为什么需要防御式编程

因为防范看似微小的错误,收获可能大到你的想象。

最简单的例子就是对输入的参数做校验,比如删除一个数据的接口需要对输入参数做校验防止产生全匹配从而删除全部数据。

如何来做

一般会结合使用断言(asset)和错误捕获及处理(try...catch)。

断言对于前端开发来说可能有些陌生,断言的语法是assert(equal, message),只要equal为假,那么message会被记录下来(对于前端来说可能是写到console中,对于后端来说可能是写到日志文件)。

两者区别在那里呢:断言来处理绝对不应该发生的状况(如果发生了,说明代码存在bug),错误处理来处理预期会发生的状况,或者说断言用来检查代码的bug,错误处理用来检查有害的输入数据

断言更多是在开发中使用的,可以更好的帮助我们在开发过程中定位错误(如果console中出现了断言的记录,我们可以顺着调用栈找到出错的源头,这比自己猜测然后加断点调试要快一些)。如果不是对性能有太大的影响的话我个人建议可以在生产环境也打开断言记录到sentry之类的日志服务中(需要注意信息的加密),这样可以更好的帮助我们定位bug。

比如从一个用户列表中删除一个用户的函数deleteUser(userId),可以使用断言来判断这个用户是不是在列表中,如果没在列表中说明肯定是代码出现了bug了(比如重复删除同一个用户或者这个函数的调用者传参数存在问题):

class User {
  constructor() {
    this.userList = [];
  }

  deleteUser(userId) {
    const isExitUser = this.userList.findIndex(user => user.id === userId) !== -1;
    asset(isExitUser, `${userId}不在用户列表中`);
  }
}

错误处理来应对预期会发生的状况,比如客户端请求了一个api接口,正常情况下这个接口返回200,但还是存在极少数的情况下这个接口会返回500,我们可以捕捉到这个错误来做一些处理,比如重新发起一次请求之类的。

fetchUserList().then((res) => {
  storeUserInfo(res.data);
}).catch((e) => {
  if (e.message = '500') {
  // TODO 这个函数还要注意下调用栈的深度,最多重复执行四次,防止调用栈过深导致爆掉
    fetchUserList();
  }
})

异常使用有这么几个原则:

  1. 如果异常可以在局部处理就在局部处理,不要放到外面去。

  2. 千万不要只捕获异常却什么都不做,比如fertchUserList().catch(() => {}),catch函数里面没有做任何处理。

  3. 抛出的异常的消息中加入异常发生的相关信息,比如如果在删除一个用户的时候,因为用户不在列表中我抛出了一个异常,那么异常就要写明白,要删除的用户的id是什么以及其他环境信息,这样可以帮助我们排查问题。

写代码的时候一定要去考虑要各种异常的情况并做好稳妥的处理,这样才能写出更加鲁棒性高并且易于debug的代码。

相关文章

  • 安全编程的实现方式

    借鉴文章 契约式编程与防御式编程 https://segmentfault.com/a/1190000007558...

  • 防御式编程

    最近业余时间在阅读《代码大全》,阅读“防御式编程”章节的时候非常受启发,自己之前对系统的错误处理这块也确实随意了。...

  • 防御式编程

    编写优秀的代码 代码是程序可识别的代码 代码是程序员可识别的代码 防御性编程 防御性编程(Defensive pr...

  • 防御式编程

    防御式编程 在防御式驾驶中要建立这样一种思维,那就是你永远也不能确定另一位司机将要做什么。这样才能够确保在其他人做...

  • 契约式编程与防御式编程

    1. 防御式编程 对于 “防御式编程” ,《代码大全》给我们提供了一个定义: 人类都是不安全、不值得信任的,所有的...

  • 防御式编程EAFP vs LBYL

    防御式编程EAFP vs LBYL EAFP:easier to ask forgiveness than per...

  • 防御式编程(二)

    《代码大全2》阅读随笔 错误处理技术 一些系统遇到错误后的指导建议 返回中立值; 换下一个正确数据; 返回前次相同...

  • 防御式编程(三)

    《代码大全2》阅读随笔 异常 异常是用来在代码中将错误或者异常传递给调用方的一种处理手段,通常有一些合理使用异常的...

  • 防御式编程(一)

    《代码大全2》阅读随笔 保护程序免遭非法输入数据的破坏 通常有三种常见的建议: 检查所有来源于外部的数据的值; 检...

  • 防御式编程(四)

    《代码大全2》阅读随笔 隔离程序,使之包容由错误造成的伤害 隔栏是一种容损策略,其目的也是为了保护程序。通常的做法...

网友评论

      本文标题:防御式编程

      本文链接:https://www.haomeiwen.com/subject/tfrldftx.html