曾經有人對函數方面提出代碼最小處理單元的概念:一個基本操作(賦值,比較等),一個函數調用(包括調用後判斷返回值進行判斷)都看成一個最小處理單元。那麼,一個函數,最小處理單元合理的個數範圍在7以內。如果超過了7,你就要考慮把他們拆分成多個函數了。
設計良好的函數往往比較小,而過大函數的設計往往一塌糊塗,或者存在很大的優化空間,函數設計的本質是內聚,它的大小隻是它的表現形式,討論一下函數的大小問題很有必要。最小數目沒有限制,即便是隻有1個,也有存在的必要。
在下面的情況下我們將函數拆分爲更小的函數:
1、一眼不能夠看到函數所有的代碼
如果函數過長,無法一眼看到一個函數所有的代碼,我會毫不猶豫的拆分。我不想讓讀者去翻屏,也不想讓讀者前顧後盼,顧此失彼。漂亮的函數應該讓讀者一眼就知道他在做什麼以及怎麼做的。
2、局部變量過多
如果局部變量超過七個,我會考慮拆分函數。變量過多意味着我要記錄太多的狀態,這會加重我大腦的負擔,同時要考慮太多的東西。這也同時意味着我可能沒有對函數功能進行深入的思考。
3、太多的縮進
太多的縮進意味着太多的嵌套,要麼是循環,要麼是判斷,都會導致複雜的邏輯。
4、不處於同一抽象層次
舉例,有一個初始化函數,需要初始化配置數據,套接字,數據庫連接,通道狀態。
Void init()
{
Config_init();
Socket_init();
Db_init();
Int I = 0;
For (I = 0;I < max_chn_num;i++)//初始化所有通道
{
G_user_chn[i].status = status_init;
……
}
}
上個函數中對所有通道的初始化一塊代碼就和其他的不處於一個抽象層次,我們應該將它封裝起來:
void chn_init()
{
Int I = 0;
For (I = 0;I < max_chn_num;i++)//初始化所有通道
{
G_user_chn[i].status =status_init;
……
}
}
函數最小可以有多小取決於它存在的意義。
接下來推薦一個我見過的最優秀的函數:
int max(int a, intb)
{
return a > b?a:b;
}
這個函數很小,只有一行,但是他存在的意義在於:在函數的調用點,我們一眼就知道是獲取a和b中的最大值,而不是分析 a > b?a:b 的邏輯。這樣可以節省程序員的腦力成本,從而達到一個目的:漂亮的函數應該讓讀者一眼就知道他在做什麼以及怎麼做的。
如果新晉的程序員對函數的大小不夠敏感,那麼,可以多嘗試編寫10行左右(甚至更小)的函數,慢慢你會發現小函數原來具有大威力。