大家剛開始編程的時候都會寫幾百行的函數(shù),結果同事看得很頭疼,最終不得不進行重構。
可是重構之前你必須深刻理解如何避免寫出過長的代碼,這樣才能指導你以后的設計不再出現(xiàn)同樣的問題。我歸納下來簡單有2個原因:
1.做到事情太多,俗稱職責太多。
2.層次復雜。
對于職責太多代碼,就是拆分,這個其實還好理解。
比如一個用戶注冊的函數(shù)就包括了注冊用戶之外的太多功能,這里如果不隱藏代碼細節(jié)的話,加起來代碼肯定要超過100行了。
function resisteUser(){
//保存用戶到數(shù)據(jù)庫
//更新用戶標簽
//發(fā)送優(yōu)惠券
//發(fā)送通知
}
我們把每個單一的功能替換成一個函數(shù),比如saveUserToDB就是把用戶保存到數(shù)據(jù)庫,這比注冊用戶能涵蓋的職責要確定很多,同時把其他代碼也封裝成函數(shù)。
function registeUser(){
//保存用戶到數(shù)據(jù)庫
saveUserToDB();
//更新用戶標簽
updateTag();
//發(fā)送優(yōu)惠券
updateCoupon();
//發(fā)送通知
notify();
}
這樣看,registeUser是一個入口函數(shù),他通過調用不同函數(shù)實現(xiàn)了用戶注冊,標簽,通知全部的功能,每個函數(shù)功能單一,可讀性增強了。
但是代碼層次復雜, 很多人不能很好的去理解。
下面看一個很多行的代碼,這個復雜嗎?
if(name="a"){
log.info("hello, mr a,are u ok" )
}
if(name="b"){
log.info("hello, mr b, you are so good" )
}
//也許需求會一直加滿a-z。。
if(name="z"){
log.info("hello, mr z, i dont like u. #$^$#^" )
}
可能你覺得這個代碼很low,加一個判斷條件都必須加一個if判斷。
但是你好好思考,假如修改點無非是加一個字母,然后打印這個字母特定的輸出信息,就算有100個分支,就算是給一個工作半年的程序員,他寫出bug的可能性也是很低,為什么?
原因就是這個函數(shù)的功能層次很單一,每個分支做的事情都是判斷條件,然后輸出內容。
舉例,業(yè)務功能和實現(xiàn)細節(jié)寫在一起就是跨層次。
隨便臆造一個業(yè)務場景,保存訂單要先查詢歷史訂單和執(zhí)行保存訂單。
1.保存訂單和執(zhí)行保存訂單到mysql,重試和事務處理。
2.查詢數(shù)據(jù)和解析查詢結果,反序列化JSON加處理字符編碼等。
壞的例子就是一個函數(shù)混合了業(yè)務操作和具體細節(jié)
function saveOrder(){
//查詢歷史訂單
queryHistoryOrder();
var res = executeSaveDb();
if(!res){
log,error("保存失敗");
res = executeSaveDb();
if(!res){
saveToCache();
}
}
}
主函數(shù)只有核心操作,保存訂單細節(jié)放到另外函數(shù)
function saveOrder(){
//查詢歷史訂單
queryHistoryOrder();
//保存訂單
save();
}
function save(){
var res = executeSaveDb();
if(!res){
log,error("保存失敗");
res = executeSaveDb();
if(!res){
saveToCache();
}
}
}
大家都聽過一句話,代碼是給人看的;
對閱讀這來說,代碼業(yè)務點是第一重要,好的結構一眼就能恰當好的展示全貌,具體細節(jié)則是需要再去了解。