2014年1月17日 星期五

軟體建構之道 Code Complete 2 筆記

Chapter 26.2 迴圈
決策外置一節的範例還有進一步改善的空間:
書中範例:
C++ Example of a Switched Loop
1:  for (i = 0 ; i < count ; i++) {  
2:    if(sumType == SUMTYPE_NET) {  
3:      netSum = netSum + amount[i];  
4:    } else {  
5:      grossSum = grossSum + amount[i];  
6:    }  
7:  }  

書中的改進範例
C++ Example of an Unswitched Loop
1:  if (sumType == SUMTYPE_NET) {  
2:    for (i = 0; i < count; i++) {  
3:      netSum = netSum + amount[i];  
4:    }
5:  } else {  
6:    for(i = 0; i < count; i++) {
7:      grossSum = grossSum + amount[i];
8:    }
9:  }  
照書中的說明:
本案例的壞處是兩個迴圈必須同時維護。如果count變更為clientCount,您必須記得在兩個地方同時變更,這對您而言是一種困擾;對必須使用程式碼的其他人而言,也會造成維護上的困擾。
事實上,我們可以更進一步,在不降低可讀性與維護性的情況下,將範例改善如下:
1:  if ( sumType == SUMTYPE_NET ) {  
2:    sum = netSum;  
3:  } else {  
4:    sum = grossSum;  
5:  }  
6:  for ( i = 0; i < count; i++) {  
7:    sum = sum + amount[i];  
8:  }  
9:  if ( sumType == SUMTYPE_NET ) {  
10:    netSum = sum;  
11:  } else {  
12:    grossSum = sum;  
13:  }  
如此一來,「兩個迴圈必須同時維護」的問題便不存在了。
甚至更進一步,考慮到未來維護時,可能會增加SUMTYPE的問題時,還可以再將迴圈單獨抽出成為一個函式:
1:  int sumAmount(int initValue)  
2:  {  
3:    int sum = initValue;  
4:    for ( i = 0; i < count; i++) {  
5:      sum = sum + amount[i];  
6:    }  
7:    return sum;  
8:  }  
再將原來的程式改為:
1:  if ( sumType == SUMTYPE_NET) {  
2:    netSum = sumAmount(netSum);  
3:  } else {  
4:    grossSum = sumAmount(grossSum);  
5:  }  
如此,便可以兼顧可讀性,維護性與效能。

沒有留言: