2012年10月30日

Exception VS Control Flow

每当提到Exeption就会有人跳出来说“Exception not use for flow control”,那到底是什么意思呢?什么情况下Exception就算控制流程了,什么时候就该抛出Exception了呢?

首先什么是Exception?

Definition: 

An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.


再看什么是“流程”?如果流程是指程序的每一步执行,那异常就是控制流程的,它就是用来区分程序的正常流程和非正常流程的,从上面异常的定义就可以看出。因此为了明确我们应该说”不要用异常控制程序的正常流程“。如何定义正常流程和非正常流程很难,这是一个主观的决定,没有一个统一的标准,只能根据实际情况。网上找个例子:
bool isDouble(string someString) {
    
try {
        
double d = Convert.ParseInt32(someString);
    } 
catch(FormatException e) {
        
return false;
    }
    
return true;
}
这个程序其实不是想convert数字,而是想知道一个字符串是否包含一个数字,通过判断是不是有异常的方式来决定返回true还是false,这是个Smell,这种应该算”异常控制了正常流程“。我们可以通过正则表达式或其他方式来判断。

另外Clean Code上一个例子:
    try {  
        MealExpenses expenses 
= expenseReportDAO.getMeals(employee.getID());  
        m_total 
+= expenses.getTotal();  
    } 
catch(MealExpensesNotFound e) {  
        m_total 
+= getMealPerDiem();  
    } 
MealExpensesNotFound异常影响了正常的计算m_total的业务逻辑。对于这种情况可以通过一下方式改进
    public class PerDiemMealExpenses implements MealExpenses {  
        
public int getTotal() {  
            
// return the per diem default  
        }  
    } 

以上两个例子是比较明显的异常控制正常流程,Smell很明显,不会有很大争议,但是实际情况中可能有很多例子没有这么明显,因为都是主观判定的。比如一下代码,算不算异常控制正常流程?

public int doSomething()
{
    doA();
    
try {
        doB();
    } 
catch (MyException e) {
        
return ERROR;
    }
    doC();
    
return SUCCESS;
}

看到这样一段程序,如果没有上下文,我们无法判断。但是如果doSomething是想让我们回答yes or no,success or error,我们不应该通过有无异常来判断yes or no,success or error,应该有个单独的方法来判断,这个方法就只做这一件事情。如果doSometing是执行一个操作,那么在这个过程中我们假定是不会出现问题的,否则抛出异常是比较合理的。






posted @ 2012-10-30 17:03 *** 阅读(149) | 评论 (0)编辑 收藏

<2012年10月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

导航

统计

常用链接

留言簿

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜