功能管理(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分鐘即可體驗的示例專案。