功能標記

2010 年 10 月 29 日

支持 FeatureBranch 最常見的論點之一是,它提供了一種機制,用於處理需要比單一發布週期更長的時間才能完成的功能。假設您每兩週發布一次產品,但需要建置一個需要三個月才能完成的功能。您要如何使用持續整合讓所有人都在主線上工作,同時在您的發布中不顯示半實作的功能?我們經常遇到這個問題,而功能標記是一個處理這個問題的便利工具。

(雖然「標記」可能是目前最流行的名詞,但「切換」仍被廣泛使用 [1]。在這篇文章中,我會交替使用這兩個名詞。)

基本概念是有一個設定檔,定義您正在處理的各種功能的一組標記。然後,正在執行的應用程式會使用這些切換來決定是否要顯示新功能。

這些決定大多發生在應用程式的使用者介面上。因此,如果您使用 jsp 建置網頁應用程式,您可以使用一組 jsp 標籤來包圍任何正在處理的功能的使用者介面部分。

    <toggle name="petSurvey">
      <p>Take our new <a href = 'petSurvey'>pet survey</a></p>
    </toggle>

切換標籤的實作,如果旗標設為開啟,則傳遞內容,否則略過內容。其他 UI 技術會使用不同的細節,但包裝待處理元素的基本概念相同。

有些功能可能是像引入新的定價演算法,其中可能沒有使用者介面元素。此處旗標的測試會在應用程式碼中,它可以像條件測試一樣粗糙,或像透過依賴性注入連接的策略一樣更精緻。

切換測試應僅出現在最少的切換點,以確保新功能正確隱藏。寵物調查功能中可能有很多畫面,但如果首頁上只有一個連結可以帶你到那裡,那麼那是唯一需要使用切換標籤保護的元素。不要嘗試使用旗標保護新功能程式碼中的每個程式碼路徑,只要專注於會引導使用者到那裡的進入點,並切換那些進入點即可。如果你發現建立、維護或移除旗標需要花費大量時間,那麼這表示你有太多切換測試。請記住,儘管簡單條件式是最容易實作切換的方式,但你應該使用多型替換等技術,以將旗標測試的點數降到最低。

到目前為止,我將功能旗標描述為你用來隱藏部分建置功能的東西,一種我稱之為發布切換的功能旗標。Hodgson 也識別了用於 A/B 測試的實驗切換、提供運作人員控制項的運作切換,以及控制不同使用者子集的功能存取權的許可切換

我聽說過的大多數功能旗標都是在執行時設定的,但我也有看過在建置時設定發布切換的案例。建置時切換的一個小優點是,新功能的程式碼不會編譯到已發布的可執行檔中。

功能切換的一個危險是意外曝光,當有人忘記將 UI 功能包裝在切換標籤中時。這很難測試,因為很難形成一個測試,即沒有任何應該隱藏的東西是可見的,而不需要呼叫出個別元素,而這些元素很可能會同時被遺忘。

我們常聽到的關於功能標記的問題是測試 - 使用功能標記是否意味著測試的組合爆炸?一般來說,不需要測試所有功能組合。對於發布標記,通常執行兩個組合就足夠了

  • 預計在下一個版本中開啟的所有標記
  • 所有標記開啟

如果您想找出任何整合錯誤,這與使用功能分支需要執行的操作大致相同。

一旦掛起的功能在生產中穩定下來,就非常重要地停用發布標記。這包括移除組態檔上的定義和所有使用它們的程式碼。否則,您將得到一堆沒有人記得如何使用的開關。我聽過一個令人難忘的例子,它需要特別重新編譯 Linux 核心才能處理足夠的命令列開關。

發布標記是您應該執行的最後一件事

發布標記是一種有用的技術,許多團隊都使用它們。但是,當您處理將功能放入生產時,它們應該是您的最後選擇。

您的第一選擇應該是分解功能,以便您可以安全地將功能的一部分引入產品。這樣做的優點與基於小型、頻繁發布的任何策略相同。您可以降低出錯的風險,並獲得使用者實際使用該功能的寶貴回饋,這將改善您稍後所做的增強功能。

如果您真的必須隱藏部分建置的功能,那麼最好的方法是使用 Keystone 介面:建置所有內容,儲存 UI 進入點,並在單一發布週期中新增該 UI。這樣,非 UI 程式碼就能與其他所有內容完全整合,但在您最後新增最後一點之前,沒有任何內容會可見或使用。

只有當您無法執行小型發布或 Keystone 介面 時,您才應該使用發布標記。

進一步閱讀

有關功能標記及其使用方式的詳細說明,請參閱 Pete Hodgson 的文章

致謝

(感謝 Charles Bradley、Kent Beck 和 Christian Gruber 的推文,提醒我一些我忘記包含的重點。)

修訂

2016-02-12 更新,以配合 Pete Hodgson 的詳細文章。2023-07-14 將網址和標題變更為「FeatureFlag」,並將文字中許多用法替換為「flag」。

備註

1: (2023 年 7 月)當 Pete 和我在 2010 年代中期最初撰寫部落格文章和文章時,同時使用了「flag」和「toggle」;連同功能位元、翻轉器、開關等。從那時起,「flag」似乎已成為最常見的術語,但我們仍看到 toggle 相當頻繁地被使用。