
阿里妹导读:关于代码的健壮性,其重要性不言而喻。那么如何才能写出健壮的代码?阿里文娱技术专家长统将从防御式编程、如何正确使用异常和 DRY 原则等三个方面,并结合代码实例,分享自己的看法心得,希望对同学们有所启发。
你不可能写出完美的软件。因为它不曾出现,也不会出现。
每一个司机都认为自己是最好的司机,我们在鄙视那些闯红灯、乱停车、胡乱变道不遵守规则的司机同时,更应该在行驶的过程中防卫性的驾驶,小心那些突然冲出来的车辆,在他们给我们造成麻烦的时候避开他。这跟编程有极高的相似性,我们在程序的世界里要不断的跟他人的代码接合(那些不符合你的高标准的代码),并处理可能有效也可能无效的输入。无效的的输入就好像一辆横冲直撞的大卡车,这样的世界防御式编程也是必须的,但要驶得万年船我们可能连自己都不能信任,因为你不知道冲出去的那辆是不是你自己的车。关于这点我们将在防御式编程中讨论。
没人能否认异常处理在 Java 中的重要性,但如果不能正确使用异常处理那么它带来的危害可能比好处更多。我将在正确使用异常中讨论这个问题。
DRY,Don't Repeat Yourself. 不要重复你自己。我们都知道重复的危害性,但重复时常还会出现在我们的工作中、代码中、文档中。有时重复感觉上是不得不这么做,有时你并没有意识到是在重复,有时却是因为懒惰而重复。
好借好还再借不难。这句俗话在编程世界中同样也是至理名言。只要在编程,我们都要管理资源:内存、事物、线程、文件、定时器,所有数量有限的事物都称为资源。资源使用一般遵循的模式:你分配、你使用、你回收。
防御式编程是提高软件质量技术的有益辅助手段。防御式编程的主要思想是:程序/方法不应该因传入错误数据而被破坏,哪怕是其他由自己编写方法和程序产生的错误数据。这种思想是将可能出现的错误造成的影响控制在有限的范围内。
一个好程序,在非法输入的情况下,要么什么都不输出,要么输出错误信息。我们往往会检查每一个外部的输入(一切外部数据输入,包括但不仅限于数据库和配置中心),我们往往也会检查每一个方法的入参。我们一旦发现非法输入,根据防御式编程的思想一开始就不引入错误。
对于非法输入的检查我们通常会使用
if…else
去做判断,但往往在判断过程中由于参数对象的层次结构会一层一层展开判断。
public void doSomething(DomainA a) {
if (a != null) {
assignAction;
if (a.getB() != null) {
otherAction;
if (a.getB().getC() instanceof DomainC) {
doSomethingB();
doSomethingA();
doSomthingC();
}
}
}
}
上边的嵌套判断的代码我相信很多人都见过或者写过,这样做虽然做到了基本的防御式编程,但是也把丑陋引了进来。《Java 开发手册》中建议我们碰到这样的情况使用卫语句的方式处理。什么是卫语句?我们给出个例子来说明什么是卫语句。
public void doSomething(DomainA a) {
if (a == null) {
return ;
}
if (a.getB() == null) {
return ;
}
if (!(a.getB().getC instanceof DomainC)) {
return ;
}
assignAction;
otherAction;
doSomethingA();