CleanCode 錯誤處理 - fantasy0107/notes GitHub Wiki

使用例外事件回傳

會讓程式碼變的乾淨, 好處理

古早

if (expression) {
	if (expression2) {
    } else {
    	logger.log('error message');
    }
} else {
	logger.log('error message');
}

現在

public class DeviceController {
    public void sendShutDown()
    {
        try {
        	tryShutDown();
        } catch (DeviceShotDwonError error) {
        	logger.log(error);	
        }
    }
    
    private void tryShutDown() throws DeviceShutDownError {
    	expression1;
        expression2;
        expression3;
    }
    
    private expression1()
    {
        ...
        throw new DeviceShutDownError('error message');
        ...
    }
}

在開頭寫下你的 try-catch-finally 敘述

1. 養成 try-catch-finally

使用不檢查型例外(use unchecked exceptions)

1. 檢查行例外在相依性所花費的工夫比實質效益還要高上不少

提供發生例外的相關資訊

一個有益的錯誤訊息 1. 讓它隨著例外訊息一起傳遞 2. 訊息中應該包含是哪個操作發生錯誤 3. 錯誤型態是甚麼

從呼叫者的角度定義例外類別

包裹第三方 API 好用得做法

比較不好的寫法

ACMPort port  = new ACEMPort(12);

try {
    port.open();
} catch (A error) {
    reportPortError(error);
    logger.log('A error message');
} catch (B error) {
    reportPortError(error);
    logger.log('B error message');
} finally {
    ...
}

比較好的寫法

localPort port = new LocalPort(12);
try {
    port.open();
} catch (PortDeviceFailure e) {
   reportError(e);
   logger.log(e.getMessage(), e);
} finally {
    ....
}


public class localPort {
    private ACMEPort innerPort
    
    public localPort(int portNumber) {
        innerPort = new ACMEPort(portnumber);
    }
    
    pubic void open() {
        innerPort.open();
    } catch(A e) {
        throw new PortDeviceFailure(e);
    } catch(B e) {
        throw new PortDeviceFailure(e);
    }  catch (C e)  {
        throw new PortDeviceFailure(e);
    }
}

定義正常的程式流程

當建立一個類別或設定一個物件, 讓它能夠替你處理特殊情況, 當你這樣做時, 客戶端就不必處理例外行為

不要回傳 null

如標題所示, 拋出例外是更好得做法

不要傳遞 null

不要將 null 傳給函式

總結

將錯誤處理看作另一件重要的事情, 將之處理成獨立於主要邏輯的可讀程式, 代表我們寫出整潔又耐用的程式碼