2010年1月19日 星期二

do while(false)

常在一些open source看到do while(false)的寫法,這樣一次call function只執行一次的code有甚麼優點呢?
可不可以用if(flag)的方式取代? 是不是覺得多此一舉或有其他更好的替代方法,討論看看。




"if" can’t break

類似以下壟長的作法
bool ExpDoWhile(bool s){
 if(s ==NULL){
  //Do other thing must do
  //clean up
  return false;
 }
 status = dosomething();
 if(status) {
  //Do other thing must do
  //clean up
  return true;
 }
 status = doSecPriority();
 if(status) {
  //Do other thing must do
  //clean up
  return true;
 }
 status = doThirdPriority();
 if(status) {
  //Do other thing must do
  //clean up
  return true;
 }
 //Do other thing must do
 //Clean Up work
 return false;
};

可以進化成
bool ExpDoWhile(bool s){
 int status = 0;
 do{
  if(s ==NULL)
   break;
  status = dosomething();
  if(status) break;
  status = doSecPriority();
  if(status) break;
  status = doThirdPriority();
  if(status) break;
 }
 while(false);
 //Do other thing must do here
 //Clean Up work

 return status;
};

這種作法也可以用goto達成,只是goto的運用總是比較危險且易犯錯
bool ExpDoWhile(bool s){
 int status = 0;

 if(s ==NULL)
  goto errorhandle;
 status = dosomething();
 if(!status) goto errorhandle;
 status = dosomething();
 if(!status) goto errorhandle;
 status = dosomething();
 if(!status) goto errorhandle;

 //Do other thing must do here
 //Clean Up work

 return true;
errorhandle:
 //clean up
 return false;

};

return once

唯一的return與一些delete release的動作可以統一放在while(false)之後管理,避免多處return與release的處理,減少將來維護犯錯的機會。
(關於這優點還是推欠之前提到的作法)

macro

最後一個關於macro使用的技巧…延伸閱讀

3 則留言:

  1. 關於這點, 我有點感到疑惑,
    之前在看 Refactoring, 其中有一個 item 叫做 "Remove Control Flag",
    作者認為 control flag(ex: status) 帶來的危害遠大於好處, 容易使程式看起來更混淆, 所以他認為該 return 的地方就 return, 這樣反而程式比較容易懂. 至於很多地方都會清資源, 我想如果利用 " Consolidate Conditional Expression" 和 "Consolidate Duplicate Conditional Fragments" 來修改程式的架構, 說不定可以同時避免很多 duplicate code (ex: 清資源).

    回覆刪除
  2. "Consolidate Conditional Expression"
    當你有一些 tests 都 return 一樣的東西, 把他們寫在單一 conditional expression 裡面.

    ex:
    BOOL canPlayNBA() {
    boolean available = NO;
    if ( m_Age > 18) available = YES;
    if ( 0 == strcmp(m_Name, "ABow") ) available = YES;
    if ( m_Skill == SUPERHIGH ) available = YES;
    return available;
    }

    -->

    BOOL canPlayNBA() {
    if ( isEligbleToPlayProfessionalBasketBall() )
    return YES;
    return NO;
    }

    回覆刪除
  3. "Consolidate Duplicate Conditional Fragments"
    假如某部份的 code 在 if else 的所有 branch 裡面都會執行, 就把這段 code 移出 if else.

    ex:

    if ( ghostHitWall() ) {
    aBowDrawShapes();
    aBowSuperShrimp();
    } else {
    aBowSayOhYeah();
    aBowSuperShrimp();
    }

    -->

    if ( ghostHitWall() ) {
    aBowDrawShapes();
    } else {
    aBowSayOhYeah();
    }
    aBowSuperShrimp();

    回覆刪除