如何編寫函數(續)----《代碼整潔之道》讀書筆記

上一篇關于函數的文章寫到編寫函數的幾個注意事項:

函數要短小。

函數只應該做一件事。

函數的參數要盡量少,避免使用輸出函數。

函數要無副作用。

函數要區分指令和詢問。

本篇接著寫關于函數的其他知識。

避免傳標識符參數給函數。標識符是指true或false。標識符參數意味著函數至少要做兩件事情:true,做一件事;false,做另一件事。我的代碼、其他同事的代碼,用標識符做參數的函數,很常見。如果要將標識從函數中消除,那么將增加函數個數,而且,在函數中由標識符帶來的if...else...結構將轉移到函數之外。這似乎沒有好處。

指令型函數要使用異常處理代替狀態碼返回。請看代碼A。

if(deleteUserById(id) === ERROR_CODE){

if(deleteUserFriendById(id) === ERROR_CODE){

return true;

}else{

log(errorMsg);

}

}else{

log(errorMsg);

}

deleteUserById(id)、deleteUserFriendById(id)都是指令型函數。將上面的代碼改造為代碼B。

try{

deleteUserById(id);

deleteUserFriendById(id);

}catch(Exception e){

log(e);

}

代碼B明顯簡潔了很多,但是我不明白:不同函數拋出的異常是不同的,捕捉到異常后進行處理的代碼也可能是不同的。假如需要針對不同的代碼,進行不同的處理,必須去了解封裝在函數內部的代碼才行。這違背了“開放—封閉”原則。工作至今,我只用過幾次此類處理錯誤的方式。需要深入函數內部去了解所拋出的異常情況,是我不使用此方式的原因。但這個方式是專家提倡的,我需慢慢琢磨,直至透徹理解它的精妙。

代碼B可以進一步改寫為代碼C。

try{

deleteUserAndFriendById(id);

}catch(Exception e){

log(e);

}

function deleteUserAndFriendById(id){

deleteUserById(id);

deleteUserFriendById(id);

}

從代碼B到代碼C,遵循著編寫函數的又一個原則:把其他大段代碼丑陋不堪的try...catch中剝離出來。至于為什么這么做,除了簡潔,我想不出其他原因。

函數命名,應該使用動詞或動詞短語+名詞的形式。例如,write(name),就是很好的函數名稱。

說點題外話。今日周五,懈怠了,中午一直在看動漫,沒有寫作。

同事前些天推薦使用markdown寫作,今天嘗試了一下。我雖然沒有掌握所有的markdown技巧,但稍加運用,就有不少好處:排版好看了些,尤其是代碼的排版。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容