ch4 The Seam Model

Seam & Enabling Point

seam(接縫)是指程式中一些特殊的點,在這些點上你不需要修改它本身就可以變動程式行為。

例如某段程式 call 了一個 function 來計算商品價格,現在想改變計算價格的 strategy。想在不改變 call 計價 function 的情況下,改變計價結果(程式行為)。

又例如程式 call 到牽連龐大子系統的 function,我們希望在 test 中避免執行到那些複雜的 code(不然很難測或無法測),又要在 prodcution code 裡照常執行到。如果這段 code 有 seam,便能在不改動到原本 call function 的情況下,換掉該 function 的行為來避免在 test 中碰到子系統。

每個 seam 都有一個 enabling point,在這裡你可以決定使用哪種行為。

seam 是可以讓你改變程式行為的「縫隙」,enabling point 則是決定那個 seam 要是什麼行為。在 enabling point 給不同的值,可以讓 seam 有不同的行為。例如物件 seam,物件 method 的參數列表是 enabling point,因為我們可以傳入不同的物件來改變程式行為。

為一團亂的 code 測試時,最好別去修改它本身,盡可能透過 seam 去解開 dependency 來測試。

Seam Types

seam 有很多種類型。不同的語言,可以使用的類型也不同。一個語言從程式碼轉換到 machine code 的各個階段,擁有不同種類的 seam。

  • preprocess 時期 seam
    • 在 C/C++ 裡可以用 macro 直接把字換掉來達到改變行為,例如直接把有 dependency 的 function call 用 #define#ifdef TESTING 時換成空的 function。
    • enabling point 是 #define TESTING
  • link 時期 seam:在將多個 object file link 起來時的 seam
    • dynamic link:直接換掉 dynamic link 要去找的 library 或 object file。
    • static link:透過 build script(像 Makefile),在測試環境去 link 抽換的 object file 而非原本 production code 的 object file。
    • enabling point 通常在 build 或 deploy script 裡,因為這時候才決定 link 誰。
  • object seam
    • 一般用 interface、polymorphism 來做 dependency injection,以及 extract and override。