功能管理(Feature management)中的 Keystone 模式

語言: CN / TW / HK

一、什麼是 Keystone ?

對軟件研發團隊來説,越是頻繁地集成他們的代碼,工作就越輕鬆。同時,越頻繁發佈功能迭代,產品就越有價值。但是團隊並不想把開發了一半的功能暴露給用户。對這種矛盾的一個有效的處理機制就是先構建所有的後端代碼,集成到產品,但不提供用户界面。這個功能可以在用户端無感知的情況下被集成和測試,直到全部完成上線後,再將這個功能展現給用户。就像是 Keystone(拱頂石,建築學術語,通常引申為確保其他部件就位的核心關鍵點)。

二、限時特價促銷活動

舉一個簡單的例子,比如説給用户推送一個限時特價商品。這樣的訂單一般都需要根據用户位置、配送情況等信息確定價格。所以根據用户位置、時間、商品類型等因素,決定了用户是否會收到這種限時特價商品的推送信息。

總而言之,這是一個很複雜的電商運作邏輯,因為需要涉及倉儲量、商品目錄、客户服務等多個系統的協同。完成這樣一個流程的開發,可能需要幾周的的時間,同時,另一些功能可能需要每隔幾天就發佈一次。而對客户而言,特價商品推送只是訂單表格上的一個選擇框。

在這個項目中,可以讓選擇框作為 Keystone。研發團隊可以跨多個產品發佈週期進行內部系統的業務邏輯和接口開發。用户感知不到這些代碼改動。最後一步是讓用户看到這個特價推送的選擇框 UI 界面,通常這用不了多少開發時間。這種模式下,所有中間代碼都能夠參與集成,並隨着產品發佈週期部署在線上,這樣就避免了長時間使用 feature branch(特性分支——一種分支管理模式)帶來的風險。

三、中間代碼和UI界面的測試方式

中間代碼需要像線上代碼一樣接受嚴格的測試。這需要系統(測試)分層搭建,而不是所有測試都依賴於用户頁面的觸發。單元測試和 Test Pyramid(測試金字塔)中的低層測試都應當可以正常執行。甚至 Broad Stack Test 都可以正常執行,只要提供一定的機制使它們成為 Subcutaneous Tests。某些情況下,UI 層本身包含了複雜的行為,不過只要設計得當,UI 也可以通過進入 Humble Object 的方式得到測試。

並非所有應用程序的構建方式都支持這種大覆蓋面的"皮下"測試,但即使無法使用 Keystone 模式,這種設計原則也是有價值的。即使用最好的工具去自動化這一過程,從 UI 層觸發的測試也總是很難搭建的。將更多的測試轉移到界面層以下各層級,特別是單元測試層,可以顯著提升部署流水線的速度,實現持續交付。

當然,大多數的 UI 變化會比添加一個選擇框複雜,即便如此,應用 Keystone模式也並不會增加太多工作量。在 Web 應用中,一個複雜的功能通常都是一個獨立頁面,可以作為一個整體構建和測試。這種場景下,Keystone 就是一個鏈接。桌面應用可能設計多個界面變化,這種情況下,Keystone 可以是一個能展示這些界面的菜單項。

儘管如此,確實存在一些場景用户界面不能被簡單地打包通過一個 Keystone 控制。這時候就需要用到功能開關了。即便在這種情況下,Keystone 的概念也能夠幫助我們將功能開關的實現限定在UI層控制上。這樣可以避免開關四處散落在後端代碼中,降低了開關應用的複雜性,更好地貫徹單開關機制,也為後續的開關清理降低了難度。

四、總結

後端先行,最後再開發 UI 界面的方式也存在一個潛在的風險,就是後端代碼的設計可能無法與後開發的UI協調一致,或者在後期UI實現時才發現設計點遺漏,這會導致反饋延遲並帶來糟糕的用户體驗。因此,只有在產品上支持功能垂直劃分,研發上能夠按功能粒度快速發佈的團隊中,Keystone 模式才能夠發揮最大的價值。

在這裏我只是舉例了一個用户界面的小例子,但同樣的方法適用於任何界面變化,例如 API。通過最後再提供用户界面,並且保持簡潔的方式,即使是很大的功能升級,我們也可以通過逐個部分增量構建、集成來完成。

在 FeatureProbe  就可以實現 Keystone 模式,做到後端代碼與UI 界面分開部署測試。研發團隊可以先開發後端代碼部署,用户側無感知這一塊功能核心功能已經部署到系統上了,確保新功能後端代碼沒有問題後,在 FeatureProbe 後台操作頁面,可以一鍵開啟 UI 界面功能,測試 UI 界面功能沒有問題後,再將這個新功能開放給用户。

目前 FeatureProbe 使用 Apache 2.0 License 協議已經完全開源。你可以從 GitHub 或Gitee 獲取到所有源碼。

與此同時,我們提供了無需部署的在線試用環境和一個僅需5分鐘即可體驗的示例項目。