本文章是由機器翻譯。

ALM Ranger

使用功能切換進行軟體開發

Bill Heys

下載代碼示例

作為一個軟體發展概念讓你追求並行、 併發功能發展作為分支 (也稱為功能分支) 的平行發展的替代,用於切換功能。有時也稱為功能切換功能標誌、 功能開關、 功能腳蹼或有條件的功能。功能切換讓你當他們正在開發的不斷整合的功能。您可以使用功能切換隱藏、 禁用或啟用個別的功能在運行時期間。

如使用所有的軟體發展技術,您將使用功能切換版本控制 (如 MicrosoftTeam Foundation伺服器) 結合。使用功能切換本身並不意味著消除所有分支從綜合版本控制計畫。功能切換的一個區別是所有的更改簽入到主分支 (靜脈注射) 而不是一個開發分支。

一種功能是禁用或隱藏從所有使用者直到你開始功能開發。在開發期間,你可以啟用為開發和單元測試,功能和所有其他使用者禁用它。品質保證 (QA) 測試人員還可以啟用他們想要測試的功能。直到該功能是完整和充分測試根目錄據做 (DoD) 的定義,並通過品質測試,它將被隱藏或禁用在發佈的軟體。沒有創建和部署新的生成,可以動態更改功能切換的值。

從開始功能分支機搆與功能切換的比較,我會建議在代碼中實現功能切換的替代方法。使用一個示例 Windows 計算機應用程式,我會說明如何隱藏或顯示在運行時使用功能切換的功能。

持續集成

使用功能切換,你可以做持續集成 — — 所有的開發工作是簽入到主分支和不斷地與在該分支中的所有其他代碼集成。在每次簽入上, 主分支中的代碼生成和使用自動生成驗證測試 (Bvt) 生成伺服器上測試。

正如所述的 Microsoft 模式 & 連續交付做法書 ("建設與Team Foundation伺服器 2012年釋放管道"[2013]),"由連續交付,我們的意思是通過版本控制、 持續集成、 自動化和環境管理等技術,您將能夠減少當你第一次有一個主意,當這種想法意識作為是在生產中的軟體之間的時間"(bit.ly/1kFV0Kx)。

您可以使用自動的單元測試來測試您的代碼之前簽入主要分支。如果簽入中斷生成的生成伺服器上,你得先檢查在允許修復代碼。如果在生成中的功能並不傳遞的 QA 測試,您可以隱藏它從部署或釋放直到它不會。

功能切換給您運行時隔離功能正在開發直到它是完整、 經過測試並準備好發佈。您使用的持續集成的功能切換,直接在主分支工作。代碼簽入到主分支,同時保持這個分支的生成和部署穩定 (見圖 1)


圖 1 功能切換支援並行開發的持續集成

在使用功能切換

圖 2 在工作示例的計算機 Windows 表單中顯示功能切換的一個示例。這也說明了平行的併發功能發展的挑戰。


圖 2 示例 Windows 計算機顯示三種新功能

這個例子比較使用功能分支到使用功能切換管理並行發展。有三個新特點 (鍵盤、 先進的功能和記憶體函數) 作為基本計算機部署在並行開發。

功能切換模式

有很多的使用模式,在其中您可以使用功能切換來允許持續集成的所有代碼,包括掛起或不完整的代碼。使用功能切換可以通過減少或消除需要並行開發的分支和隨後進行分支和合併可以是非常耗時而且容易出錯的任務,提高團隊的發展速度。

這裡是典型的方案,你可以考慮功能切換的清單:

  • 隱藏或禁用 UI 中的新功能
  • 隱藏或禁用應用程式中的新元件
  • 版本控制介面
  • 擴展介面
  • 支援元件的多個版本
  • 將一個新的功能添加到現有的應用程式
  • 加強現有的功能在現有的應用程式

為功能隔離分支

功能的分支策略,與您的團隊可以隔離特定功能的並行或並行開發 — — 或群體的特徵 — — 入單獨的功能的分支。功能分支機搆給你在何時釋放進入生產方面的極大靈活性。你不必等待,直到所有的功能都準備好了要做一個全面的部署。

您可以輕鬆地合併個別的功能組到主分支時他們完全依國防部。你可以根據需要,創建新功能分支和刪除他們一旦完成該功能。直到他們滿足國防部的功能不被合併到主分支。下面的例子中, 圖 3 顯示了三個新功能分支提供隔離期間並行發展。


圖 3 為功能隔離分支

有關各種功能分支方案的更多指導,你可以引用ALM Rangers電子書籍的分支策略在 aka.ms/vsarsolutions

功能切換 vs。功能分支機搆

使用功能切換讓您和您的團隊追求持續集成、 連續部署和連續釋放的做法。這些做法允許更頻繁的功能代碼集成作為他們開發並行相比功能分支時。同時,功能切換還支援運行時隔離的正在開發功能和沒有準備好釋放。

與功能的切換,所有暫止的變更簽入到主分支。每個檢查中也會掛起直到自動的生成過程生成主分支中的所有代碼生成的伺服器上,並成功運行自動化 Bvt。這是稱為持續集成的過程。

在運行時,功能切換隱藏或繞過中生成,但不是準備發佈功能。根據您計畫如何實現一種功能,使用功能切換的努力有時可能過於複雜。另一方面,隱藏功能從 UI 可以是簡單的。

當使用功能分支,所有發展是簽入關聯的功能分支,從主分支或其他功能分支中的代碼分離。不能合併新的或增強的功能與主分支或其他功能分支,直至功能代碼完成,通過必要的品質測試,或符合 DoD。只有在此時,功能集成 (合併) 與主分支。因此,代碼隔離和持續集成是在有些兩端的"一體化頻譜"。

啟用部署中的新功能是相對比較容易和免費的風險。只需啟動關聯的功能切換到可見並已啟用。發佈一項新功能,使用功能分支的努力是複雜得多。您必須將該功能合併到主分支。這往往是時間-­消費及富有挑戰的過程。

刪除功能

在一些專案中,要刪除或重新出不完整的功能。回滾回滾功能 (櫻桃採摘的更改) 的單個變更集也是複雜的、 勞動密集型和可能需要大量的代碼返工。

它是必須隔離功能從主分支,直到您決定釋放的那些功能。在任何情況下,只是之前版本計畫從釋放退出一項功能是風險大且容易出錯。使用功能之間切換,可以將所有功能的所有代碼都簽入主要分支。功能切換只是隱藏或禁用選擇功能從運行時或釋放。

執行選項

有多個方法對持續存在的應用程式的功能切換狀態。這裡有兩個相當簡單的方法:

  1. 使用應用程式設定來定義功能切換 (部署在 XML 應用程式佈建檔中生成應用程式時)。
  2. 存儲功能切換作為資料庫表中的行。

定義功能切換不只是在設定檔中使用設置設計器,定義功能切換容易,但你不需要做任何事情在應用程式中保存狀態的功能切換,當在應用程式結束時。中所示的示例設置檔圖 4 定義功能切換。


圖 4 為 Windows 計算機此示例 ConfigSettings 檔存儲功能切換狀態

存儲資料庫行作為功能切換使用功能切換資料庫表來存儲功能切換狀態,應用程式將需要兩個設置檔。CommonSettings 設置檔定義了應用程式所使用的選項。DatabaseSettings 設置檔的控制項是否在切換功能定義和保存在資料庫表 (為 True 時) 或在設置檔中 (當為 False 時)。FeatureToggleSettings 檔提供的你就會在資料庫中存儲的功能切換每個名稱 (請參見圖 5)。


圖 5 功能切換名稱存儲在資料庫表中作為行

Windows 計算機的示例中使用的方法是可以動態地創建功能切換行。當第一次運行應用程式時,表將為空。在運行時,所有的功能切換名稱檢查,看他們是否啟用。如果任何表中是不是已經,應用程式將它們向表中添加。中的示例 FeatureToggle 表圖 6 所有功能添加切換行的顯示。


圖 6 FeatureToggle 表後首次運行

執行獨立概念

當您使用功能切換要禁用功能時,應用程式中的代碼隱藏或禁用基於功能切換 (真/假) 與該功能相關聯的值的控制項。您可以選擇要完全從正在開發,功能的 UI 隱藏功能或顯示該功能為禁用。當你釋放功能時,它將可見並已啟用。

圖 7 顯示只有小鍵盤功能與 Windows 計算機,可見並已啟用。記憶體功能和先進的功能特性是可見的但卻是禁用。


圖 7 Windows 計算機小鍵盤功能可見並已啟用,以及記憶體和先進的功能特點可見和已禁用

此應用程式範例中的第一步創建一個新的 FeatureToggleDemo 資料庫,接著創建一個簡單的 FeatureToggle 表。當您下載的應用程式範例時,您將會找到三個 SQL 檔:創建 FeatureToggle 資料庫、 創建 FeatureToggle 表,以及創建應用程式用於載入值從和拯救他們回到 FeatureToggle 的表的兩個存儲的過程。

在創建後的 FeatureToggle 表,不是需要添加任何 FeatureToggle 行之前第一次應用程式運行。該應用程式使用 FeatureToggle 類庫來封裝的所有應用程式邏輯用於訪問和更新功能切換。

下面的代碼顯示私有欄位用於保存功能切換的狀態:

private Boolean _IsKeyPadFeatureEnabled = false;
private Boolean _IsKeyPadFeatureVisible = false;
private Boolean _IsMemoryFeatureEnabled = false;
private Boolean _IsMemoryFeatureVisible = false;
private Boolean _IsAdvancedFeatureVisible = false;
private Boolean _IsAdvancedFeatureEnabled = false;

中的代碼圖 8 演示如何從存儲在 ConfigSettings 檔中的功能切換值設置私有欄位。

圖 8 功能切換值存儲在 ConfigSettings File 中

private void GetFeatureTogglesFromSettings()
{  
  _IsKeyPadFeatureEnabled = 
    Properties.ConfigSettings.Default.KeyPadFeatureEnabled;
  _IsKeyPadFeatureVisible = 
    Properties.ConfigSettings.Default.KeyPadFeatureVisible;
  _IsMemoryFeatureEnabled = 
    Properties.ConfigSettings.Default.MemoryFeatureEnabled;        
  _IsMemoryFeatureVisible = 
    Properties.ConfigSettings.Default.MemoryFeatureVisible;
  _IsAdvancedFeatureEnabled = 
    Properties.ConfigSettings.Default.AdvancedFeatureEnabled;
  _IsAdvancedFeatureVisible = 
    Properties.ConfigSettings.Default.AdvancedFeatureVisible;
  tbMode.Text = Constants.configSettings;
}

中的代碼圖 9 演示如何從存儲在 FeatureToggle 資料庫表中的功能切換值設置私有欄位。

圖 9 設置私有欄位從資料庫表中存儲的存儲的功能切換值

private void GetFeatureTogglesFromStore()
{
  _IsKeyPadFeatureEnabled = FeatureToggles.FeatureToggles.IsEnabled(
    Properties.FeatureToggleSettings.Default.KeyPadFeatureEnabled);
  _IsKeyPadFeatureVisible = FeatureToggles.FeatureToggles.IsEnabled(
    Properties.FeatureToggleSettings.Default.KeyPadFeatureVisible);
  _IsMemoryFeatureEnabled = FeatureToggles.FeatureToggles.IsEnabled(
    Properties.FeatureToggleSettings.Default.MemoryFeatureEnabled);
  _IsMemoryFeatureVisible = FeatureToggles.FeatureToggles.IsEnabled(
Properties.FeatureToggleSettings.Default.MemoryFeatureVisible);
  _IsAdvancedFeatureEnabled = FeatureToggles.FeatureToggles.IsEnabled(
    Properties.FeatureToggleSettings.Default.AdvancedFeatureEnabled);
  _IsAdvancedFeatureVisible = FeatureToggles.FeatureToggles.IsEnabled(
    Properties.FeatureToggleSettings.Default.AdvancedFeatureVisible);
  tbMode.Text = Constants.databaseSettings;
}

中的代碼圖 10 顯示了應用程式如何評估功能切換和設置的可見和已啟用屬性的使用包裝方法的 Windows 計算機功能。

圖 10 使用包裝方法來設置 Windows 計算機的可見的和啟用的屬性

private void EvaluateFeatureToggles()
  {
    this.tbVersion.Text = Properties.CommonSettings.Default.Version;
    if (Properties.CommonSettings.Default.DatabaseSettings)
    {
      GetFeatureTogglesFromStore();
    }
    else
    {
      GetFeatureTogglesFeatureToggleFromSettings();
    }
    if (_IsAdvancedFeatureEnabled)
    {
      _IsAdvancedFeatureVisible = true;
    }
    SetAdvancedFeatureEnabled(_IsAdvancedFeatureEnabled);
    SetAdvancedFeatureVisible(_IsAdvancedFeatureVisible);
  }

下面的代碼演示一個包裝函數,以隱藏或顯示與先進的功能功能關聯的使用者介面元素:

private void SetAdvancedFeatureVisible(bool state)
{
  this.btnBkspc.Visible = state;           
  this.btnSqrt.Visible = state;
  this.btnPercent.Visible = state;
  this.btnReciprocal.Visible = state;
  this.btnPlusMinus.Visible = state;
}

Windows 計算機利用可重用的類庫來封裝與 FeatureToggle 表相關聯的所有處理。 使用此類庫,使用 ConfigSettings 檔的代碼,是使用 FeatureToggle 的資料庫表的代碼幾乎完全相同。

總結

功能切換的好處是新功能或增強功能已簽入到主分支,所以它們可以不斷集成和測試的現有基本代碼在生成時。 以前,從新功能或增強功能的代碼通常不集成了具有基本代碼直到接近的釋放期限,是高風險、 具有挑戰性和充滿危險。 兩個功能之間切換,並且功能分支是可行的辦法,你可以使用實現僅完成功能,這些功能已經通過必要的 QA 測試的穩定版本。 選擇要使用一個或另一個取決於您的需要和發展進程中的地方。

Bill Heys 是一位高級 ALM 設計過程和解決方案顧問。他以前是 Microsoft ALM 一位高級顧問。他是微軟Visual StudioALM Rangers,別動隊分支和合併指導開發人員主管和釋放的別動隊版本控制指導貢獻的成員。聯繫到他在 bill.heys@live.com

衷心感謝以下技術專家對本文的審閱:MichaelFourie (獨立顧問),Micheal Learned(Microsoft),馬太福音 》 Mitrik (Microsoft) 和Willy-Peter Schaub(Microsoft)