本章從資料導向的觀點轉向以述句(statement)為中心,探討最基本的控制流程:循序執行。雖然組織直線碼(straight-line code)看似簡單,但排列方式會影響程式的正確性、可讀性與可維護性。

14.1 必須有明確順序的述句#

當述句之間存在**相依性(dependency)**時,執行順序至關重要。最直觀的例子是:

data = ReadData();
results = CalculateResultsFromData(data);
PrintResults(results);

這裡的相依關係從函式名稱就能看出。但實務中,相依性往往被隱藏。例如某個函式暗中初始化了其他函式需要的類別成員變數,從呼叫端根本看不出執行順序的要求。

當述句之間有順序相依性時,必須採取措施讓這些相依性顯而易見。

讓順序相依性變得明確的技巧#

  • 組織程式碼使相依性明顯:不要讓某個函式偷偷兼做初始化。應獨立出 InitializeExpenseData() 這類函式,從名稱就能看出它必須先被呼叫。

  • 用命名揭示相依性:如果一個函式同時做了計算和初始化,至少讓名稱反映全部職責。名稱長不可怕,可怕的是函式本身職責不清。

  • 用參數揭示相依性:透過傳遞共用資料,暗示執行順序的重要性。更好的做法是讓每個函式接收輸入並回傳更新後的資料:

expenseData = InitializeExpenseData(expenseData)
expenseData = ComputeMarketingExpense(expenseData)
expenseData = ComputeSalesExpense(expenseData)
expenseData = ComputeTravelExpense(expenseData)
expenseData = ComputePersonnelExpense(expenseData)
DisplayExpenseSummary(expenseData)

當各函式使用不同的資料參數時,則反過來暗示它們的執行順序無關緊要。

  • 用註解說明不明顯的相依性:先嘗試讓程式碼本身表達順序,若仍不夠清楚再用註解補充。記錄程式碼假設(coding assumptions)是撰寫可維護程式碼的關鍵。

  • 用斷言或錯誤處理檢查相依性:對關鍵程式碼,可使用狀態變數(如 isExpenseDataInitialized)搭配斷言(assertion)來驗證前置條件是否滿足。但要注意,這會增加額外的變數、初始化與檢查邏輯,帶來新的出錯機會,需權衡利弊。

優先順序:讓程式碼結構自明 > 用命名和參數暗示 > 用註解補充 > 用斷言強制檢查。

flowchart TB
    A["最高優先:程式碼結構自明"] --> B["次優先:命名和參數暗示"]
    B --> C["再次:註解補充"]
    C --> D["最後手段:斷言強制檢查"]

    style A fill:#2d6a4f,color:#fff
    style B fill:#40916c,color:#fff
    style C fill:#52b788,color:#fff
    style D fill:#95d5b2,color:#000

14.2 順序無關的述句#

當述句之間沒有執行順序的相依性時,仍應依據**鄰近原則(Principle of Proximity)**來安排:把相關的操作放在一起。

讓程式碼從上往下讀#

反面範例:變數宣告集中在一起,接著各種物件的季度計算混在一起,然後年度計算又混在一起。閱讀者必須在整段程式碼中來回追蹤單一物件的使用軌跡。

改善方式是將同一物件的所有操作集中:

MarketingData marketingData;
marketingData.ComputeQuarterly();
marketingData.ComputeAnnual();
marketingData.Print();

SalesData salesData;
salesData.ComputeQuarterly();
salesData.ComputeAnnual();
salesData.Print();

TravelData travelData;
travelData.ComputeQuarterly();
travelData.ComputeAnnual();
travelData.Print();

這樣組織的好處:(1) 各物件的引用被局部化(localized);(2) 變數的存活範圍(live time)縮短;(3) 自然暗示可拆分為獨立函式的重構機會。

將相關述句分組#

相關述句的判斷依據:操作相同資料、執行類似任務、或彼此有順序相依。一個簡單的測試方法是列印程式碼,將相關述句用方框圈起來——如果方框不重疊(或只有巢狀),代表分組良好;如果方框互相交叉,就需要重新組織。

當一組高度相關的述句與前後文沒有有意義的關聯時,應考慮將其重構為獨立的函式。

要點#

  • 組織直線碼最重要的原則是依照順序相依性排列
  • 應透過良好的函式命名、參數列表、註解,以及必要時的狀態變數,讓相依性顯而易見
  • 當程式碼沒有順序相依性時,依據鄰近原則讓相關述句盡量靠近
  • 程式碼應能從上往下閱讀,避免讀者來回跳躍
  • 高度相關且自成一體的述句群組,是重構為獨立函式的好候選