最近一直担忧Dubbo分布式服务框架后续若是维护人员增多或变动,会出现质量的降低,
我在想,有没有什么是须要你们共同遵照的,
根据平时写代码时的一习惯,总结了一下在写代码过程当中,尤为是框架代码,要时刻牢记的细节,
可能下面要讲的这些,你们都会以为很简单,很基础,但要作到时刻牢记,
在每一行代码中都考虑这些因素,是须要很大耐心的,
你们常常说,魔鬼在细节中,确实如此。
1. 防止空指针和下标越界
这是我最不喜欢看到的异常,尤为在核心框架中,我更愿看到信息详细的参数不合法异常,
这也是一个健状的程序开发人员,在写每一行代码都应在潜意识中防止的异常,
基本上要能确保一次写完的代码,在不测试的状况,都不会出现这两个异常才算合格。
2. 保证线程安全性和可见性
对于框架的开发人员,对线程安全性和可见性的深刻理解是最基本的要求,
须要开发人员,在写每一行代码时都应在潜意识中确保其正确性,
由于这种代码,在小并发下作功能测试时,会显得很正常,
但在高并发下就会出现莫明其妙的问题,并且场景很难重现,极难排查。
3. 尽早失败和前置断言
尽早失败也应该成为潜意识,在有传入参数和状态变化时,均在入口处所有断言,
一个不合法的值和状态,在第一时间就应报错,而不是等到要用时才报错,
由于等到要用时,可能前面已经修改其它相关状态,而在程序中不多有人去处理回滚逻辑,
这样报错后,其实内部状态可能已经混乱,极易在一个隐蔽分支上引起程序不可恢复。
4. 分离可靠操做和不可靠操做
这里的可靠是狭义的指是否会抛出异常或引发状态不一致,
好比,写入一个线程安全的Map,能够认为是可靠的,
而写入数据库等,能够认为是不可靠的,
开发人员必须在写每一行代码时,都注意它的可靠性与否,
在代码中尽可能划分开,并对失败作异常处理,
并为容错,自我保护,自动恢复或切换等补偿逻辑提供清晰的切入点,
保证后续增长的代码不至于放错位置,而致使原先的容错处理陷入混乱。
5. 异常防护,但不忽略异常
这里讲的异常防护,指的是对非必须途径上的代码进行最大限度的容忍,
包括程序上的BUG,好比:获取程序的版本号,会经过扫描Manifest和jar包名称抓取版本号,
这个逻辑是辅助性的,但代码却很多,初步测试也没啥问题,
但应该在整个getVersion()中加上一个全函数的try-catch打印错误日志,并返回基本版本,
由于getVersion()可能存在未知特定场景异常,或被其余的开发人员误修改逻辑(但通常人员不会去掉try-catch),
而若是它抛出异常会致使主流程异常,这是咱们不但愿看到的,
但这里要控制个度,不要随意try-catch,更不要无声无息的吃掉异常。
6. 缩小可变域和尽可能final
若是一个类能够成为不变类(Immutable Class),就优先将它设计成不变类,
不变类有自然的并发共享优点,减小同步或复制,并且能够有效帮忙分析线程安全的范围,
就算是可变类,对于从构造函数传入的引用,在类中持有时,最好将字段final,以避免被中途误修改引用,
不要觉得这个字段是私有的,这个类的代码都是我本身写的,不会出现对这个字段的从新赋值,
要考虑的一个因素是,这个代码可能被其余人修改,他不知道你的这个弱约定,final就是一个不变契约。
7. 下降修改时的误解性,不埋雷
前面不停的提到代码被其余人修改,这也开发人员要随时紧记的,
这个其余人包括将来的本身,你要总想着这个代码可能会有人去改它,
我应该给修改的人一点什么提示,让他知道我如今的设计意图,
而不要在程序里面加潜规则,或埋一些容易忽视的雷,
好比:你用null表示不可用,size等于0表示黑名单,
这就是一个雷,下一个修改者,包括你本身,都不会记得有这样的约定,
可能后面为了改某个其它BUG,不当心改到了这里,直接引爆故障。
对于这个例子,一个原则就是永远不要区分null引用和empty值。
8. 提升代码的可测性 这里的可测性主要指Mock的容易程度,和测试的隔离性, 至于测试的自动性,可重复性,非偶然性,无序性,完备性(全覆盖),轻量性(可快速执行), 通常开发人员,加上JUnit等工具的辅助基本都能作到,也能理解它的好处,只是工做量问题, 这里要特别强调的是测试用例的单一性(只测目标类自己)和隔离性(不传染失败), 如今的测试代码,过于强调完备性,大量重复交叉测试, 看起来没啥坏处,但测试代码越多,维护代价越高, 常常出现的问题是,修改一行代码或加一个判断条件,引发100多个测试用例不经过, 时间一紧,谁有这个闲功夫去改这么多形态万千的测试用例? 长此以往,这个测试代码就已经不能真实反应代码如今的情况,不少时候会被迫绕过, 最好的状况是,修改一行代码,有且只有一行测试代码不经过, 若是修改了代码而测试用例还能经过,那也不行,表示测试没有覆盖到, 另外,可Mock性是隔离的基础,把间接依赖的逻辑屏蔽掉, 可Mock性的一个最大的杀手就是静态方法,尽可能少用。