這是一個讓我糾結了很久的話題:縮進。
for (int j = 0; j < attributes.size(); j++) { Attr *attr = attributes.get(j); if (attr == NULL ) { continue; } int IsCallFunc = -1; if(attr->status() == STATUS_NEW || attr->status() == STATUS_MODIFIED) { if(strcmp(attr->attrID(), "CallFunc") == 0) { if(0 == strcmp(attr->attrValue(), "1")) { IsCallFunc = 1; } else if(0 == strcmp(attr->attrValue(), "0")) { IsCallFunc = 0; } } } else if (attr->status() == STATUS_DELETED) { IsCallFunc = 0; } ... }
不是因爲它不夠“醜”,而是表現它不那麼容易。找出一段能表現它特點的代碼輕而易舉,但放到一篇文章裏,大片的代碼還是容易讓人懷疑我在偷懶。
咬咬牙,我還是拿出了一段。就是這樣一段已經縮進很多層的代碼,實際上,也只不過是一個更大縮進中的一小段。而且,省略號告訴我們,後面還有。
回到這段代碼上,能出現多層縮進,for循環功不可沒。出現這種循環,很多情況下,都是對一個集合進行處理,而循環裏的內容,就是對集合裏的每一個元素進行處理。這裏也不例外。所以,我們先做一次提取:
for (int j = 0; j < attributes.size(); j++) { processAttr(attributes.get(j)); } void processAttr(Attr *attr) { if (attr == NULL ) { return; } int IsCallFunc = -1; if(attr->status() == STATUS_NEW || attr->status() == STATUS_MODIFIED) { if(strcmp(attr->attrID(), "CallFunc") == 0) { if(0 == strcmp(attr->attrValue(), "1")) { IsCallFunc = 1; } else if(0 == strcmp(attr->attrValue(), "0")) { IsCallFunc = 0; } } } else if (attr->status() == STATUS_DELETED) { IsCallFunc = 0; } ... }
至此,我們去掉了一層縮進,而且因爲這個提取,語義也變得很清晰:這個新函數只是處理集合裏的一個元素。
接下來,這個函數裏面長長的代碼是對IsCallFunc進行設值,後面省略的部分會根據這裏求出的結果進行處理。所以,這裏把processAttr進一步分拆:
void processAttr(Attr *attr) { if (attr == NULL ) { return; } int IsCallFunc = isCallFunc(attr); ...... } int isCallFunc(Attr *attr) { if(attr->status() == STATUS_NEW || attr->status() == STATUS_MODIFIED) { if(strcmp(attr->attrID(), "CallFunc") == 0) { if(0 == strcmp(attr->attrValue(), "1")) { return 1; } else if(0 == strcmp(attr->attrValue(), "0")) { return 0; } } } else if (attr->status() == STATUS_DELETED) { return 0; } return -1; }
縮進還有,如果有興趣,還可以繼續分解。這裏就到此爲止吧!
多層縮進是那種放在代碼海一眼就可以認出來的代碼,用一條簡單的規則就可以限制它:
- 不允許出現多層縮進。
按照我的喜好,3就意味着“多”了。對於switch,我會給予特別的關照,因爲switch一旦出場,條件少了,你都不好意思和人打招呼,再縮進就找不到北了。於是,對switch而言,我以爲2就是多了,也就是說,switch裏面就別再縮進了。
寫代碼,千萬別退讓太多。
作者簡介:
鄭曄,ThoughtWorks公司諮詢師,擁有多年企業級軟件開發經驗,熱衷於探索各種程序設計語言在真實軟件開發中所能發揮的威力,致力於探尋合理的軟件開發方式,加入ThoughtWorks公司後,投入到敏捷開發方法的實踐之中,爲其他公司提供敏捷開發方法方面的諮詢服務。他的blog是夢想風暴。