2007年12月13日 星期四

軟體建構之道 (Code Complete) 第二版 第十七章到第十九章心得

軟體建構之道

第十七章-異常控制結構

使用保護子句簡化複雜的錯誤處理

if (checkUserName() == true)
{
  if (checkPassword() == true)
  {
    if (checkBirthday() == true)
    {
      if (checkCertificationPhoto() == true)
      {
        // lots of code.
      }
    }
  }
}

改寫為

if (checkUserName() == false)
{
  /* 可加上錯誤提示. */
  return;
}

if (checkPassword() == false)
{
  /* 可加上錯誤提示. */
  return;
}

if (checkBirthday() == false)
{
  /* 可加上錯誤提示. */
  return;
}

if (checkCertificationPhoto() == false)
{
  /* 可加上錯誤提示. */
  return;
}

/* 通過以上重重考驗才能抵達此處. */
// lots of code.

前者若要加上錯誤提示,又會產生出一堆 else 區塊. 後者則不會降低閱讀性. 不過 return 應該要小心使用就是. Orz

謹慎使用 goto

以下引述自書中:

使用 goto 會違反程式碼應該完全由上而下流動的原則.

我自己在考古別人的程式碼時,也最討厭看到跳來跳去的邏輯,總之謹慎使用會改變程式碼流程的語法.

第十八章-資料表導向法

書上先是舉了個取出每個月天數的範例,與其在程式中寫出以下程式碼:

if (month = 1)
{
  return 31;
}
else if (month = 2)
{
  return 28;
}
...
..(落落長的程式碼)..
...
else if (month = 12)
{
  return 31;
}

不如直接建立一個每月天數的陣列,也就是一個存在於記體的資料表,直接查表就不需要寫出一長串無聊的條件判斷了.

int[] daysOfMonth =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int daysOfJuly = daysOfMonth[7 - 1]; // 直接查表. 此處可以搬出成一個常式,來處理 -1 的邏輯.

看完這例子,我只覺得超簡單,這樣也能寫成一章. 書上接著舉了一個 "彈性訊息格式" 的範例,我只能說 "我錯了!!",我對這個範例一點 Sence 都沒有啊. 囧rz

有興趣的人請自己翻書來看,以下心得請不要認真看,算是自己解釋給自己看的東西,完全不知道正不正確.

系統內有 20 種資訊格式,因為每種資訊內的欄位都不一樣,書中將 "如何解讀資訊" 的動作包裝出來:
Hard cord: 類似每月取天數的例子,一種解讀資訊的方法就寫在一個 if 裡頭.
OOP: 建立一個解讀資訊的繼承樹,或是使用 Strategy Pattern 來封裝不同的解讀方式.

好戲上場. Orz
資料表:
1. 先定義出欄位會出現哪些型別(int, String...).
2. 利用 1 定義出的型別,建立每種資訊用來解讀的 meta data,系統內會有 20 個這樣的 meta data,這些 meta data 集合就是一個資料表(可以存在檔案內).
3. 建立讀取欄位型別的共用常式.
4. 系統接收到一個資訊,它就根據資訊編號去資料表找出對應的 meta data,然後透過 3 建立的常式就能解讀資訊.

好處是若又有新的資訊,我們不用更動程式碼,只需要在資料表建立新的 meta data. 程式碼變少了,因為都轉成 meta data(但我還是要寫 囧).

我承認,這章我看得超痛苦,我對含有 meta-data 這種例子的東西真的很不行. 我覺得我之後又會忘光光了. Orz

第十九章-一般性控制問題

以隱含的方式將布林式作真及假

不要寫 while (isDone == false) 而寫成 while (!isDone) .
不要寫 while ((a > b) == true) 而寫成 while (a > b).

這樣的好處是不用記太多項數,讀起來也較像是對話式的英文. 不過我忘記我在哪裡看到,最好不要在在條件判斷中使用 "!" .

while (!isDone) // 我看這句腦中是浮現 while ((!isDone) == true) , 反而更亂.
while (isDone == false) // 我很直覺就把 isDone 想成變數,它要等於 false 才會執行.

反而我覺得看個人啦,我思考方式比較像電腦,念起來順不順不重要,我只關心 isDone 是一個變數,它要等於 false 才會執行. Orz

以數線順序編寫數字運算式

(MIN <= i && i <= MAX)
(i >= MIN && MAX >= i)

哪一個看起來比較有感覺? 哪一個一看就知道 i 的範圍?

---- MIN ---- i ---- MAX ----

這樣還看不出來? 那這一個重點你可以跳過. Orz

書上有一段話我覺得很不賴,跟大家共勉之.

寧可努力找出好的解決方法並避開失敗,也不要嘗試找出最佳的解決辦法.

又找到了個偷懶的好理由了. Orz

0 則回應:

Related Posts Plugin for WordPress, Blogger...