编码建议--魔鬼在细节
防止空指针和下标越界
这是我最不喜欢看到的异常,尤其在核心框架中,我更愿看到信息详细的参数不合法异常,
这也是一个健状的程序开发人员,在写每一行代码都应在潜意识中防止的异常,
基本上要能确保一次写完的代码,在不测试的情况,都不会出现这两个异常才算合格。
保证线程安全性和可见性
对于框架的开发人员,对线程安全性和可见性的深入理解是最基本的要求,
需要开发人员,在写每一行代码时都应在潜意识中确保其正确性,
因为这种代码,在小并发下做功能测试时,会显得很正常,
但在高并发下就会出现莫明其妙的问题,而且场景很难重现,极难排查。
尽早失败和前置断言
尽早失败也应该成为潜意识,在有传入参数和状态变化时,均在入口处全部断言,
一个不合法的值和状态,在第一时间就应报错,而不是等到要用时才报错,
因为等到要用时,可能前面已经修改其它相关状态,而在程序中很少有人去处理回滚逻辑,
这样报错后,其实内部状态可能已经混乱,极易在一个隐蔽分支上引发程序不可恢复。
分离可靠操作和不可靠操作
这里的可靠是狭义的指是否会抛出异常或引起状态不一致,
比如,写入一个线程安全的Map,可以认为是可靠的,
而写入数据库等,可以认为是不可靠的,
开发人员必须在写每一行代码时,都注意它的可靠性与否,
在代码中尽量划分开,并对失败做异常处理,
并为容错,自我保护,自动恢复或切换等补偿逻辑提供清晰的切入点,
保证后续增加的代码不至于放错位置,而导致原先的容错处理陷入混乱。
异常防御,但不忽略异常
这里讲的异常防御,指的是对非必须途径上的代码进行最大限度的容忍,
包括程序上的BUG,比如:获取程序的版本号,会通过扫描Manifest和jar包名称抓取版本号,
这个逻辑是辅助性的,但代码却不少,初步测试也没啥问题,
但应该在整个getVersion()中加上一个全函数的try-catch打印错误日志,并返回基本版本,
因为getVersion()可能存在未知特定场景异常,或被其他的开发人员误修改逻辑(但一般人员不会去掉try-catch),
而如果它抛出异常会导致主流程异常,这是我们不希望看到的,
但这里要控制个度,不要随意try-catch,更不要无声无息的吃掉异常。
缩小可变域和尽量final
如果一个类可以成为不变类(Immutable Class),就优先将它设计成不变类,
不变类有天然的并发共享优势,减少同步或复制,而且可以有效帮忙分析线程安全的范围,
就算是可变类,对于从构造函数传入的引用,在类中持有时,最好将字段final,以免被中途误修改引用,
不要以为这个字段是私有的,这个类的代码都是我自己写的,不会出现对这个字段的重新赋值,
要考虑的一个因素是,这个代码可能被其他人修改,他不知道你的这个弱约定,final就是一个不变契约。
降低修改时的误解性,不埋雷
前面不停的提到代码被其他人修改,这也开发人员要随时紧记的,
这个其他人包括未来的自己,你要总想着这个代码可能会有人去改它,
我应该给修改的人一点什么提示,让他知道我现在的设计意图,
而不要在程序里面加潜规则,或埋一些容易忽视的雷,
比如:你用null表示不可用,size等于0表示黑名单,
这就是一个雷,下一个修改者,包括你自己,都不会记得有这样的约定,
可能后面为了改某个其它BUG,不小心改到了这里,直接引爆故障。
对于这个例子,一个原则就是永远不要区分null引用和empty值。
提高代码的可测性
这里的可测性主要指Mock的容易程度,和测试的隔离性,
至于测试的自动性,可重复性,非偶然性,无序性,完备性(全覆盖),轻量性(可快速执行),
一般开发人员,加上JUnit等工具的辅助基本都能做到,也能理解它的好处,只是工作量问题,
这里要特别强调的是测试用例的单一性(只测目标类本身)和隔离性(不传染失败),
现在的测试代码,过于强调完备性,大量重复交叉测试,
看起来没啥坏处,但测试代码越多,维护代价越高,
经常出现的问题是,修改一行代码或加一个判断条件,引起100多个测试用例不通过,
时间一紧,谁有这个闲功夫去改这么多形态各异的测试用例?
久而久之,这个测试代码就已经不能真实反应代码现在的状况,很多时候会被迫绕过,
最好的情况是,修改一行代码,有且只有一行测试代码不通过,
如果修改了代码而测试用例还能通过,那也不行,表示测试没有覆盖到,
另外,可Mock性是隔离的基础,把间接依赖的逻辑屏蔽掉,
可Mock性的一个最大的杀手就是静态方法,尽量少用。
原文地址《魔鬼在细节》
编码建议--魔鬼在细节相关推荐
- Dubbo | 魔鬼在细节中
本文转载自:http://javatar.iteye.com/blog/1056664 作者javatar 如有转载,请标明原贴地址和作者,谢谢 最近一直担心Dubbo分布式服务框架后续如果维护人员增 ...
- 上国会中外合作办学金融EMBA课程 |魔鬼在细节里——《财务报告与价值分析》课程报道
无需参加全国联考获国家承认双证中国教育部留学服务中心可认证 一个个有趣的资本市场问题,在19期EMBA<财务报告与价值分析>课堂上重现和解读.课程主讲老师上海财经大学孙铮教授,现任上海财经 ...
- 自己收藏:魔鬼在细节中
转自http://javatar.iteye.com/blog/1056664 最近一直担心Dubbo分布式服务框架后续如果维护人员增多或变更,会出现质量的下降, 我在想,有没有什么是需要大家共同遵守 ...
- Go 编码建议——风格篇
文章目录 1.格式化 主体风格 占位符 2.代码行 行长度 换行方式 不必要的空行 括号和空格 行数 3.字符串 4.依赖管理 依赖规范 import 规范 5.初始化 初始化 struct 初始化 ...
- Go 编码建议——性能篇
文章目录 常用数据结构 1.反射虽好,切莫贪杯 1.1 优先使用 strconv 而不是 fmt 1.2 少量的重复不比反射差 1.3 慎用 binary.Read 和 binary.Write 2. ...
- Go 编码建议——功能篇
文章目录 1.不需要指向 interface 的指针 2.编译期验证 interface 合理性 3.接收器为值和指针实现接口的区别 4.零值 Mutex 是有效的 5.在边界处拷贝 slice 和 ...
- 给刚入坑的ACMer一些编码建议(1)——使用“好”变量名
我们打竞赛的,一般都特别喜欢用长度很短的一些变量名,比如a, a1, i, j呀. 至于为什么,原因可能包括: 提高编码效率(冠冕堂皇) 图方便,懒得想变量名(主要原因) 受其他选手的编程风格影响(次 ...
- 魔鬼在细节,理解Java并发底层之AQS实现
jdk的JUC包(java.util.concurrent)提供大量Java并发工具提供使用,基本由Doug Lea编写,很多地方值得学习和借鉴,是进阶升级必经之路 本文从JUC包中常用的对象锁.并发 ...
- Go 编码建议——项目布局
文章目录 1.前言 2.项目布局 2.1 整体风格 2.2 Go 代码目录 /cmd /internal /pkg /vendor 2.3 服务应用程序目录 /api 2.4 Web 应用程序目录 / ...
最新文章
- 2014-04-03研究笔记整理
- 二分查找对应的二叉树的成功和失败ASL
- 判断丑数python_LintCode Python 简单级题目 517.丑数
- codewars??? Is my friend cheating?
- 与时间相关的java源码_Java 调整日期和时间
- 【Clickhouse】Clickhouse MergeTree家族引擎
- 搭建IntelliJ IDEA+maven+jetty+SpringMVC 开发环境(二)
- plsql 存储过程 批量提交_浅谈PetShop之使用存储过程与PLSQL批量处理(附案例)
- ISD9160学习笔记08_结项总结
- 零基础:21天搞定Python分布爬虫
- 西门子1200控制V90伺服,西门子1200通过PN通讯控制 V90伺服,程序控制采用FB285功能块
- 2016/5/21 Seperate by *
- java+ElementUI前后端分离旅游项目第六天 移动端开发下
- 如何在iPhone之间共享您的Wi-Fi密码?
- java单例模式几种常见实现方式
- 4.16 使用可选颜色命令调整图像色彩 [原创Ps教程]
- vivos9设置定时开关机方法分享
- Qt制作一个简单的电子时钟
- 小学生学数学c语言编程,用C语言做出小学生数学应用题的感觉
- 价值投资3原则:内在价值、安全边际和市场波动
热门文章
- drop_duplicates去重详解
- 为什么 VS Code 会这么牛逼?
- Direct3D模板技术
- php浮动边框设置属性,CSS float 浮动属性
- ESXi虚拟机的磁盘格式
- Ajax-实现Google Suggest风格搜索
- LEADTOOLS 入门教程: 添加引用并设置许可证 - C# .NET Core
- Java程序员必备!java课程百度网盘下载
- java.exe不是内部或外部命令_javac错误:javac不是内部或外部命令 也不是可运行的程序 解决方法...
- python飞船小游戏