Keystone 介面
2020 年 4 月 29 日
軟體開發團隊如果能盡可能頻繁地整合工作,會發現生活輕鬆許多。他們也發現頻繁地發佈到生產環境很有價值。但團隊不想讓半成品功能曝光在使用者面前。處理這種緊張關係的一個有用技巧是建構所有後端程式碼,進行整合,但不要建構使用者介面。這個功能可以整合和測試,但 UI 會保留到最後,就像拱心石一樣,加入後完成這個功能,讓使用者看到。
這個技巧的一個簡單範例可能是讓客戶選擇加急訂單。這種訂單需要定價,具體取決於客戶居住的地點和在那裡營運的配送公司。所涉及商品的性質會影響倉庫中使用的揀貨方式。某些客戶可能有資格使用加急訂單,這也可能取決於配送地點、時間和訂購的商品種類。
總而言之,這是一大堆業務邏輯,特別是因為它將涉及與各種倉儲、目錄和客戶服務系統的複雜整合。這可能會花費數週時間,而其他功能需要每隔幾天就發佈一次。但對使用者而言,加急訂單只是訂單表單上的核取方塊。
為了使用核心的核取方塊來建置此功能,團隊在數個生產版本中針對基礎業務邏輯和內部系統介面進行開發工作。使用者並不知道所有這些潛在程式碼。只有在最後一個步驟中,才需要讓核心的核取方塊可見,這可以在相對較短的時間內完成。這樣,所有潛在程式碼都可以整合,並成為系統的一部分,進而投入生產,減少長期功能分支所帶來的問題。

潛在程式碼需要經過與實際啟用時相同的可信度測試。如果系統架構的設定方式,讓大部分測試不用透過使用者介面進行,就可以做到這一點。單元測試和測試金字塔的其他較低層級,應該可以輕鬆執行此類測試。即使廣泛堆疊測試也可以執行,只要有讓它們成為皮下測試的機制即可。在某些情況下,使用者介面本身會有很多行為,但如果設計允許可見的使用者介面成為謙卑物件,也可以測試這些行為。
並非所有應用程式都建置得如此完善,可以廣泛地以皮下方式進行測試,但即使沒有使用核心的能力,這樣做也是值得的。即使有最佳的工具來自動化流程,透過使用者介面執行的測試,設定起來總是比較麻煩。將更多測試移到皮下和較低層級的測試,尤其是單元測試,可以大幅加速部署管線,並啟用持續傳遞。
當然,大多數使用者介面會比核取方塊更複雜,不過它們通常不需要更多的核心工作。在網路應用程式中,複雜的功能通常會是一個獨立的網頁,可以完整建置和測試,而核心只是一個連結。桌機可能有幾個畫面,核心的功能是讓它們可見的選單項目。
話雖如此,有些時候使用者介面無法封裝成一個簡單的核心。如果是這樣,就該使用功能旗標了。然而,即使在這種情況下,思考核心還是很有用的,因為這樣可以確保功能切換只套用到使用者介面上。這可以避免在後端程式碼中散佈許多切換點,降低套用切換的複雜性,允許使用簡單的切換機制,並在適當時機更容易移除。
最後開發 UI 有一個通則的危險,在於後端程式碼可能以一種方式設計,一旦建立後就無法與 UI 一起使用,或 UI 沒有獲得它需要的關注,直到很晚,導致缺乏迭代和不良的使用者體驗。由於這些原因,關鍵石方法在整體方法中運作得最好,該方法鼓勵透過薄垂直切片建立產品,從而快速釋出小型但完全運作的功能。
我這裡使用使用者介面的範例,但當然相同的做法可以用於任何其他介面,例如 API。透過最後建立使用者的介面,並保持其簡潔,我們可以建立並整合甚至大型功能於小型區塊中。
暗黑啟動是一種變形,其中新功能在建立後會被呼叫一次,但不會向使用者顯示任何結果。這樣做是為了衡量對後端系統的影響,這對於某些變更很有用。一旦一切都很好,我們就可以新增關鍵石。
致謝
我第一次接觸到這種技術的關鍵石隱喻是在 Kent Beck 的第二版極限編程精要中。Pete Hodgson、Brandon Duff 和 Stefan Smith 提醒我我忘記了這一點。
Dave Farley、Paul Hammant 和 Pete Hodgson 對這篇文章的草稿發表了評論。