Introduce Assertion (引入断言)

Summary 某一段代码需要对程序状态做出某种假设。以断言明确这表现这种假设。

                                               094140_YSpr_134516.png

动机: 常常会有这样一段代码:只有当某个条件为真时,该段代码才能正常运行。例如平方根计算只对正直才能进行,又例如某个对象可能假设其字段至少有一个不等于null

这样的假设通常并没有在代码中明确表现出来,你必须阅读整个算法才能看出。有时程序员会以注释写出这样的假设。而我们要介绍的是一种更好的技术:使用断言明确标明这些假设。

断言首先是一个条件表达式,应该总是为真。如果它失败,表示程序员犯了错误。因此断言的失败应该导致一个非受控异常(unchecked exception)。断言绝对不能被系统的其他部分使用。实际上,程序最后的成品往往将断言统统删除。因此标记“某些东西是个断言”是很重要的。

断言可以作为交流与调试的辅助。在交流的角度上,断言可以帮助程序阅读者理解代码所做的假设;在调试的角度上,断言可以在距离bug最近的地方抓住它们。

做法:

如果程序员不犯错,断言就应该不会对系统运行造成任何影响,所以加入断言永远不会影响程序的行为。

如果你发现代码假设某个条件始终为真,就加入一个断言明确说明这种情况。

à你可以新建一个Assert类,用于处理各种情况下的断言。

注意,不要滥用断言。请不要使用它来检查“你认为应该为真”的条件,请只用它来检查“一定必须为真”的条件。滥用断言可能会造成难以维护的重复逻辑。在一段逻辑中加入断言是有好处的,因为它迫使你重新考虑这段代码的约束条件。如果不满足这些约束条件,程序也可以正常运行,断言就不会带给你任何帮助,只会把代码变得混乱,并且有可能妨碍以后的修改。

你应该常常问自己:如果断言指示的约束条件不能满足,代码是否仍能正常运行?如果可以,就把断言拿掉。

另外,还需要注意断言中的重复代码。它们合其他任何地方的重复代码一样不好闻。你可以大胆使用Extract Method去掉那些重复代码。

范例:

   下面是一个简单的例子:开支限制。后勤部门的员工每个月有固定的开支限额;业务部门的员工则按照项目的开支限额来控制自己的开支。一个员工可能没有开支额度可用,也可能没有参与项目,但两者总要有一个(否则就没有经费可用了)。在开支限额相关程序中,上述假设总是成立的,因此:

class Employee...
    private static final double NULL_EXPENSE = -1.0
    private doulbe _expenseLimit = NULL_EXPENSE;
    private Project _primaryProject;
    
    double getExpenseLimt(){
        return (_expenseLimit != NULL_EXPENSE)? 
            _expenseLimit : 
            _primaryProject.getMemberExpenseLimit();
    }
    
    boolean withinLimint(doulbe expenseAmount){
        return (expenseAmount <= getExpenseLimit());
    }

这段代码包含了一个明显假设:任何员工要么参与某个项目,要么有个人开支限额。我们可以使用断言在代码中更明确地指出这一点:

double getExpenseLimt(){
   Assert.isTrue(_expenseLimit != NULL_EXPENSE || _primaryProject !=null);
   return (_expenseLimit != NULL_EXPENSE)? 
            _expenseLimit : 
            _primaryProject.getMemberExpenseLimit();
}

这条断言不会改变程序的任何行为。另一方面,如果断言中的条件不为真,我们就会受到一个运行期异常:也许是withinLimit()函数抛出一个空指针异常,也许是在Assert.isTrue()函数中抛出一个运行期异常。有时断言可以帮助程序员找到bug,因为它离出错地点很近。但是,更多时候,断言的价值在于:帮助程序员理解代码正确运行的必要条件。


转载于:https://my.oschina.net/u/134516/blog/214542

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值