「設計良好的函式往往比較小,而過大函式的設計往往一塌糊塗,或者存在很大的優化空間。」也許你認為討論函式的大小沒有必要,原因是函式設計的本質是內聚,它的大小只是它的表現形式。而上面的原因有必要讓我們討論一下函式的大小問題。
我對函式的核心思路:我提出**最小處理單元的概念:乙個基本操作(賦值,比較等),乙個函式呼叫(包括呼叫後判斷返回值進行判斷)都看成乙個最小處理單元。那麼,乙個函式,最小處理單元合理的個數範圍在7以內。如果超過了7,你就要考慮把他們拆分成多個函式了(為什麼是7?人同時能夠處理的資訊不超過7個)。
最小數目沒有限制,即便是只有1個,也有存在的必要。
在下面的情況下我會將函式拆分為更小的函式:
1、一眼不能夠看到函式所有的**。
如果函式過長,無法一眼看到乙個函式所有的**,我會毫不猶豫的拆分。我不想讓讀者去翻屏,也不想讓讀者前顧後盼,顧此失彼。漂亮的函式應該讓讀者一眼就知道他在做什麼以及怎麼做的。
2、區域性變數過多。
如果區域性變數超過七個,我會考慮拆分函式。變數過多意味著我要記錄太多的狀態,這會加重我大腦的負擔,同時要考慮太多的東西。這也同時意味著我可能沒有對函式功能進行深入的思考。
3、太多的縮排。
太多的縮排意味著太多的巢狀,要麼是迴圈,要麼是判斷,都會導致複雜的邏輯。
4、如果你在使用ctrl+c和ctrl+v
那你寫的**不夠拽(dry,don't repeat yourself)。這個時候,你要把你複製的部分拆分為新的函式。
5、不處於同一抽象層次。
舉例,有乙個初始化函式,需要初始化配置資料,套接字,資料庫連線,通道狀態。
void init() }
上個函式中對所有通道的初始化一塊**就和其他的不處於乙個抽象層次,我們應該將它封裝起來:void chn_init() }
函式最小可以有多小,它存在的意義我見過的最優秀的函式:
int max(int a, intb)
這個函式很小,只有一行,但是他存在的意義在於:在函式的呼叫點,我們一眼就知道是獲取a和b中的最大值,而不是分析a > b?a:b的邏輯。這樣可以節省程式設計師的腦力成本,從而達到乙個目的:漂亮的函式應該讓讀者一眼就知道他在做什麼以及怎麼做的。
小函式的最大障礙:效能
對於程式設計師新手,小函式的最大障礙在於沒有經驗體會不到小函式的優勢,沒有經驗拆分大函式為更小的函式。
對於有一定經驗的程式設計師,小函式的最大障礙也許是對效能的憂慮。
對於效能,切記,不要過早優化。我們一般認為的程式的瓶頸,一般並不是程式的瓶頸:我們需要工具來確定真正的瓶頸所在,20%的**耗費了80%的效能,優化之前首先要找到那20%的**。函式呼叫會產生資源和效能的損耗,但是這是不是程式的效能瓶頸?消耗的效能佔總體的效能百分比為多少?這一切在**編寫時並不清楚,所以,我的觀點是寧可選擇簡短的函式來獲得清晰簡單的設計,以便在專案後期能夠更快,更好的進行效能優化。
很多人都在質疑我上面列舉的max函式的例項,如果說他在執行期間呼叫次數不大,則對效能的影響基本可以忽略,而獲得的可讀性,清晰性這極具價值;反過來,如果他的呼叫次數是否龐大,以致成為了效能的瓶頸,則完全可以在程式編寫完成後,很快的用其他的方法優化。程式的瓶頸不會很多。
關於函式呼叫產生的效能消耗,我會抽時間測試一下,看到底占用多少。
最後的建議:
在對新員工培訓的過程中,發現程式設計師新手一般對函式的大小不夠敏感。所以,我建議你可以多嘗試編寫10行左右(甚至更小)的函式,慢慢你會發現小函式原來具有大威力。
函式要多小才夠好 談小函式之道
設計良好的函式往往比較小,而過大函式的設計往往一塌糊塗,或者存在很大的優化空間。也許你認為討論函式的大小沒有必要,原因是函式設計的本質是內聚,它的大小只是它的表現形式。而上面的原因有必要讓我們討論一下函式的大小問題。我對函式的核心思路 我提出 最小處理單元的概念 乙個基本操作 賦值,比較等 乙個函式...
函式要多小才夠好 談小函式之道
設計良好的函式往往比較小,而過大函式的設計往往一塌糊塗,或者存在很大的優化空間。也許你認為討論函式的大小沒有必要,原因是函式設計的本質是內聚,它的大小只是它的表現形式。而上面的原因有必要讓我們討論一下函式的大小問題。我對函式的核心思路 我提出 最小處理單元的概念 乙個基本操作 賦值,比較等 乙個函式...
函式要多小才夠好 談小函式之道
設計良好的函式往往比較小,而過大函式的設計往往一塌糊塗,或者存在很大的優化空間。也許你認為討論函式的大小沒有必要,原因是函式設計的本質是內聚,它的大小只是它的表現形式。而上面的原因有必要讓我們討論一下函式的大小問題。我對函式的核心思路 我提出 最小處理單元的概念 乙個基本操作 賦值,比較等 乙個函式...