代碼之醜(九)——退讓的縮進

這是一個讓我糾結了很久的話題:縮進。

 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是夢想風暴

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章