將模組化架構連結至開發團隊
行動裝置案例研究
模組化架構可以改善軟體交付嗎?可以!- 但有一些但書。本文記載了一家企業的歷程,他們著手將其架構轉移到更模組化的架構,以緩解其成長的痛苦。他們發現模組化是一個多方面的解決方案,其範圍不僅限於架構,還延伸到業務溝通管道、團隊拓撲和有效的開發人員體驗。透過密切注意這些因素,該企業能夠大幅提升其行動應用程式的交付效能。
2023 年 6 月 13 日
本文將說明不同的行動擴充問題、技術架構和團隊之間的直接連結。在 Thoughtworks,我們與許多大型企業合作,每家企業在擴充其行動裝置影響力時,都會提出不同的問題和需求。我們找出大型企業行動應用程式開發中常見的兩個問題
- 將新功能導入市場應用程式所需的時間逐漸拉長
- 由於內部市場應用程式之間缺乏相容性/可重複使用性,而產生的內部功能差異
本文記錄了我們的客戶在嘗試解決這些問題時所經歷的過程。我們將敘述他們的組織在過去如何傾向於正確的解決方案,但由於誤解這些解決方案是如何內在連結的,因此無法看到預期的效益。
我們透過回顧同一組織如何透過將其團隊拓撲轉換為符合模組化架構,同時投資於開發人員體驗,進而將平均週期時間縮短 60%、開發成本改善 18 倍,以及團隊啟動成本降低 80% 來發展此觀察。
辨識徵兆
儘管有最好的意圖,軟體經常會隨著時間而惡化,無論是在品質或效能方面。功能需要更長的時間才能推向市場,服務中斷變得更嚴重且需要更長的時間才能解決,經常導致從事產品開發的人員感到沮喪和失去參與感。其中一些問題可以歸因於程式碼及其維護。然而,將責任完全歸咎於程式碼品質,對於這個多面向的問題來說似乎過於天真。惡化傾向於隨著時間而加劇,透過產品決策、康威定律、技術負債和靜態架構的複雜交互作用而產生。
在這個時候,似乎有必要介紹本文所依據的組織。這是一個非常大型的企業,這項業務已經經歷了將新功能導入其零售行動應用程式所需時間逐漸拉長的現象。
作為開端,該組織正確地將他們所經歷的摩擦歸因於隨著應用程式成長而增加的複雜性,他們現有的開發團隊努力增加與現有功能保持一致且相容的功能。他們對此的最初反應是「只要增加更多開發人員」;而這對他們來說確實有效,達到某種程度。然而,最終顯而易見的是,增加更多人員會以更緊張的溝通為代價,因為他們的技術主管開始感受到增加的協調開銷。因此,亞馬遜推廣了雙披薩團隊規則:任何團隊都應該小到可以用兩個披薩餵飽。理論上,透過限制團隊的規模,你可以避免溝通管理花費的時間多於實際創造價值的時間。這是合理的理論,並且對亞馬遜有很大的幫助。然而,在考慮一個已經變得過大的現有團隊時,會傾向於「崇拜儀式」亞馬遜的範例,以嘗試減輕負擔……
限制認知負擔
的確,該組織也不例外:他們曾經的小型巨石已變得越來越成功,但隨著功能、責任和團隊成員的增加,也無法複製所需的成功率。隨著迫在眉睫的功能交付期限和多個品牌市場的前景,他們通過將現有團隊拆分為多個較小的連接子小組來應對 - 每個團隊都是孤立的,管理著一個單獨的市場(儘管客戶旅程相似)。
事實上,這讓情況對他們來說變得更糟,因為它將溝通成本從他們的技術領導層轉移到了實際團隊本身,同時並沒有減輕他們不斷擴大的上下文負載。意識到溝通和協調會耗費那些負責實際價值創造的人越來越多的時間,我們的最初建議涉及 Skelton & Pais (2019) 概述的「認知負載限制」概念。這涉及跨越單一複雜或複雜領域的團隊分離。軟體內的這些接縫可用於制定上述「兩個披薩大小的團隊」。結果是每個團隊的開銷大大減少:動力上升,使命宣言更清晰,而溝通和上下文切換被縮小到一個單一的共享焦點。理論上,這是解決我們客戶問題的絕佳方案,但如果孤立地考慮,實際上可能會產生誤導。只有在應用程式的領域邊界在程式碼中得到真正明確定義和持續尊重時,才能真正實現認知負載限制的好處。
領域驅動規範
領域驅動設計 (DDD) 對於將複雜邏輯組織成可管理的群組,並為每個群組定義共同的語言或模型很有用。然而,將應用程式分解成領域只是持續進行中的流程的一部分。嚴格控制 邊界脈絡 與定義領域本身一樣重要。在檢視客戶的應用程式程式碼時,我們遭遇了常見的陷阱,即在定義和組織領域責任時進行了明確的初期投資,但隨著應用程式的成長,這種紀律開始受到侵蝕。來自利害關係人的軼事證據顯示,持續忙碌的團隊為了滿足緊急產品需求而採取捷徑已成為團隊的常態。這反過來又導致技術債務累積,使得價值傳遞逐漸減緩。隨著程式碼發布變得更加困難,除錯問題也變得更加困難,這進一步突顯了應用程式的 四個關鍵指標 中可衡量的下降趨勢。
透過常見的程式碼分析工具,我們發現了邊界脈絡管理不善的更多警示徵兆。我們發現程式碼庫已經成長到緊密耦合且缺乏內聚力。高度耦合的程式碼 很難在不影響系統其他部分的情況下進行變更。內聚力低的程式碼有許多不符合其職責範圍的責任和考量,這使得難以理解其目的。隨著客戶應用程式中每個領域的複雜性增加,這兩個問題都隨著時間而惡化。其他跡象再次與認知負載有關。應用程式中領域之間的邊界或依賴關係不明確,這表示對其中一個領域進行變更時,可能會不由自主地影響其他領域。我們注意到,由於這個原因,開發團隊需要具備多個領域的知識才能解決任何可能中斷的問題,這會增加認知負載。對於組織而言,對每個領域邊界脈絡實施嚴格控制是確保知識和責任置於同一個地方的進步措施。這會限制任何變更的「爆炸半徑」,無論是在工作量或所需的知識方面。此外,在累積和處理技術債務時引入更嚴格的控制,可確保任何短期的「領域流失」可以在其擴大之前被拒絕或糾正。
組織的行動應用程式中缺少的另一個指標是可重複使用的選擇性。如前所述,有多個現有的成熟品牌市場應用程式。這些應用程式之間的功能一致性很低,而且由於希望個別市場具有自主性,因此難以統一成單一的行動應用程式。系統中的緊密耦合降低了在其他地方重複使用領域的能力:為了在另一個市場重複使用一個領域,必須移植現有行動應用程式的絕大部分,這會帶來很高的整合和持續管理成本。我們適當地控制領域邊界脈絡,這是邁向模組化的第一步,方法是避免直接依賴其他領域。但正如我們發現的那樣,這不是我們需要採取的唯一行動。
超越應用程式的領域
情境 1 -「整潔的巨石」
當視為單一應用程式時,只要將應用程式分割成網域,指派一個團隊,並管理它們的耦合(以不違反它們的界定內容),就能很好地運作。以一個功能要求為例,針對個別應用程式

功能要求會傳遞給擁有相關網域的應用程式小組。我們嚴格的界定內容表示我們變更的爆炸半徑會包含在自身內,表示我們的功能可以在不變更我們應用程式的其他部分的情況下建置、測試甚至部署。我們加快了我們的上市時間,並允許多個功能同時獨立開發。太棒了!
確實,這在單一市場環境中運作良好。然而,一旦我們嘗試解決我們的第二個擴充問題 - 由於缺乏可重複使用性而產生的市場功能差異 - 我們開始遇到問題。
情境 2 -「下一個市場機會」
組織在尋求網域模組化的過程中,下一步是透過將「整齊巨石」的部分移植到現有的市場應用程式中,以實現快速的開發節省。這涉及建立一個共用架構(我們稍後會討論其面向),允許功能/網域在來源外部的手機應用程式中重複使用。為了更好地說明我們的做法,以下範例顯示兩個市場應用程式,一個在英國,另一個是美國的新應用程式。我們的美國應用程式團隊已決定除了他們美國特定的網域外,他們還希望將忠誠點數和結帳網域用於他們的應用程式,並已將它們匯入。

對組織而言,這似乎意味著他們的市場團隊可以節省大量的開發成本,相較於他們傳統的網域功能重寫行為。然而,這並非故事的結局——在我們急於朝向模組化邁進時,我們未能考量到組織現有的溝通結構,而這最終決定了工作的優先順序。發展我們先前的範例作為說明:在美國團隊於其自有市場使用網域後,他們想到了一個新功能,可以在其中一個他們導入的網域中使用。他們並未擁有或具備該網域的背景知識,因此他們聯繫英國應用程式團隊並提交功能要求。英國團隊接受了請求並表示聽起來「是個好主意」,但他們目前「正在處理來自英國利害關係人的請求」,因此無法確定他們何時可以開始進行這項工作...

我們發現,在網域功能優先順序上出現的利益衝突,限制了共用功能使用者可以預期的重複使用量——這從市場團隊對於導入網域進度緩慢感到沮喪中顯而易見。我們對問題提出了一些解決方案理論:使用團隊或許可以分岔他們自己的網域版本,並圍繞它組織一個團隊。然而,正如我們已經知道的,為了新增少量功能而學習/擁有整個網域是沒有效率的,而且分歧也會為市場間未來的升級或功能同等性共用帶來問題。我們研究的另一個選項是透過拉取請求進行貢獻。然而,這會對貢獻團隊施加其本身的認知負擔——迫使他們在第二個程式碼庫中工作,同時仍然依賴主要網域團隊在跨團隊貢獻上的支援。例如,尚不清楚網域團隊在他們自有市場的功能開發之間是否有足夠的時間提供架構指導或公關審查。
情境 3 -「市場不可知領域」
顯然問題出在我們團隊的組織方式。康威定律觀察到一個組織會設計其業務系統以反映其本身的溝通結構。我們先前的範例描述了一個場景,其中功能在技術觀點上是模組化的,但在所有權觀點上仍然是整體的:「忠誠點數最初是為英國應用程式建立的,因此屬於該團隊」。對此潛在的回應之一說明在反向康威變招中。這涉及變更開發團隊的結構,以便讓他們能讓所選的技術架構浮現。
在以下範例中,我們從先前的場景進展,並對我們的團隊進行結構變更,以反映我們先前擁有的模組化架構。網域從特定行動應用程式中抽象出來,而本身則是自主的開發團隊。當我們這樣做時,我們注意到應用程式團隊之間的關係發生了變化,因為他們不再依賴市場之間的功能。取而代之的是,我們發現新的關係形成,而這些關係以消費者和供應商的術語更能描述。我們的網域團隊向其市場客戶提供功能,而市場客戶反過來使用這些功能,並回饋新的功能要求,以更好地開發網域產品。

這種重組相較於我們先前的迭代所具有的主要優勢是焦點的明確化。先前我們描述了當一個市場提出要求,要求變更來自另一個市場的網域時發生的利益衝突。將網域從其市場中抽象出來,將焦點從僅為市場利益而建構任何功能轉變為更全面的任務,即建構滿足其消費者需求的功能。成功開始根據消費者採用率和最終使用者接收情況來衡量。任何新功能都僅根據其為網域及其消費者整體帶來的價值量進行檢閱。
專注於開發人員體驗以支援模組化
回顧一下,該組織現在有一個拓撲結構,支援跨市場的元件模組化。自主團隊被分配網域以擁有和開發。市場應用程式簡化為組態容器。在概念上,這一切都是有道理的 — 我們可以很輕鬆地規劃回饋如何從消費者流向供應商。我們也可以做出高層烏托邦假設,例如:「所有網域都是獨立開發/部署的」或「消費者『僅』拉入他們希望用來形成應用程式的任何可重複使用的網域」。
然而,在實務上,我們發現這些是難以解決的技術問題。例如,您如何在自主網域團隊之間維持 UX/品牌一致性?當您僅負責整體應用程式的一部分時,您如何啟用行動應用程式開發?您如何允許網域的可發現性?可測試性?跨市場的相容性?解決這些問題完全有可能,但會施加其本身的認知負載,而這項責任在我們目前的結構中沒有明確的所有者。所以我們做了一個!
解決核心問題的領域
我們的全新網域被歸類為「平台」。平台基本上是一個我們用來描述工具和指導的包羅萬象的術語,讓我們的團隊能夠在所選架構中獨立交付。我們的全新網域團隊維護我們已經看到的供應商/消費者關係,並負責改善在平台中建置其應用程式和網域的團隊的開發人員體驗。我們假設更強大的開發人員體驗將有助於推動我們的新架構的採用。
但是「開發人員體驗」(DX) 是一個非常不具體的術語,因此我們認為定義我們的全新團隊提供良好體驗所需的內容非常重要。我們將 DX 網域細分為一組必要的機能,第一個是有效引導。
對於任何常見架構,都有不可避免的學習曲線。良好的開發人員體驗旨在盡可能降低該曲線的嚴重性。明智的預設值和入門套件是一種非專制的減少加入時感受到的摩擦的方式。我們為我們的平台網域定義的一些範例
我們承諾
- 您將能夠使用一個指令快速產生一個新的網域,其中包含所有相關的行動依賴關係、常見的 UI/UX、遙測和 CI/CD 基礎架構
- 您將能夠獨立建置、測試和執行您的網域
- 您的網域在打包到應用程式中時,將會以與獨立執行時相同的方式執行
請注意,這些承諾描述了開發人員生產力平台中自助服務體驗的元素。因此,我們將有效的開發人員平台視為一個允許專注於最終使用者功能的團隊專注於他們的任務,而不是努力克服看似無止盡的非生產性任務清單的平台。
我們為平台網域識別的第二個必要功能是技術架構即服務。在組織中,架構功能也遵循康威定律,因此架構決策的責任集中在一個獨立的孤島中,與需要指導的團隊脫節。我們的自主團隊雖然能夠做出自己的決策,但往往需要「技術引導」的某些方面才能在原則、模式和組織治理上保持一致。當我們將這些需求外推到隨選服務中時,我們創造了類似以下的內容
我們承諾
- 我們提供的最佳實務將附有您可以使用的範例或您可以採取的實際步驟
- 我們將維護每個應用程式的網域使用概況,並在需要時協調跨垂直領域的合作
- 生產路徑將是可見且正確的
- 我們將與您合作
請注意,這些承諾描述了與團隊的僕人領導關係,承認每個人都對架構負責。這與有些人可能描述為命令和控制架構治理政策相反。
關於平台網域的最後一點,以及值得從前一個範例中重新檢視的一點。根據我們的經驗,成功的平台團隊是與客戶需求緊密結合的團隊。在豐田精益生產中,「現場現物」大致翻譯為「親自去看」。其理念是親自拜訪問題的根源並親眼所見,才能知道如何解決問題。我們了解到,專注於改善開發人員體驗的團隊必須能夠對使用其產品的開發人員感同身受,才能真正了解他們的需求。當我們第一次創建平台團隊時,我們並沒有給予此原則應有的關注,只看到我們的自主團隊找到了自己的方法。這最終導致了工作的重複、不相容以及對架構缺乏信心,而這需要時間才能糾正。
結果
我們已經說明了我們如何將行動應用程式模組化,但隨著時間推移,它的成功程度如何?取得實證證據可能很困難。根據我們的經驗,在同一個組織內擁有舊有應用程式和新架構的應用程式,使用相同的網域並為兩者提供傳遞指標,這種情況並不多見。然而,幸運的是,在這個例子中,組織夠大,可以一次轉換一個應用程式。對於這些結果,我們比較了兩個功能相似的零售應用程式。一個舊有應用程式具有高度耦合和低凝聚力,儘管有一個高生產力和成熟的開發團隊(「舊有巨石」)。另一個是我們先前描述的模組化重構練習的結果 - 一個定義明確且管理良好的有界上下文,但有「較新的」個別網域團隊支援(「有界上下文應用程式」)。週期時間是一個很好的衡量標準,因為它表示在程式碼中「進行」變更所需的時間,並且不包括將應用程式推送到應用程式商店 - 一個應用程式類型無關的變長度程序。
行動應用程式類型 | 週期時間 |
---|---|
舊有巨石 | 17 天 |
有界上下文(平均) | 10.3 天 |
即使在我們的第二個應用程式中,週期時間在所有網域團隊中取平均值,我們也看到與經驗較少的團隊相比,舊有應用程式有顯著的提升。
我們的第二次比較涉及可重複使用的選擇性,或缺乏選擇性。在這個情況下,我們檢查組織中相同的兩個行動應用程式。同樣地,我們比較一個需要現有網域功能(別無選擇,只能自己撰寫)的應用程式與我們的模組化應用程式(能夠插入和播放現有的網域)。我們忽略了生產過程中常見的步驟,因為它們對我們所測量的內容沒有影響。相反地,我們專注於開發團隊可以控制的面向,並從預生產「產品簽核」到開發完成,衡量我們的開發程序,由一對開發人員與一位全職設計師合作。
整合類型 | 平均開發時間 |
---|---|
非模組化 | 90 天 |
模組化 | 5 天 |
上述截然不同的數字顯示了模組化架構在有業務需求的設定中的力量。
順帶一提,值得注意的是,我們排除的這些外部因素也應該納入考量。最佳化開發效能可能會揭露整體流程中的其他瓶頸。例如,如果建立一個版本需要 6 個月,而治理需要 1 個月才能核准,那麼治理在流程中所佔的比例相對較小。但是,如果開發時程可以縮短到 5 天,而核准仍然需要 1 個月,那麼合規性可能會成為下一個需要最佳化的瓶頸。
上述結果中未呈現的另一個優勢是,圍繞網域組織的團隊對整合活動的影響。我們發現,自主網域團隊會自然而然地將自己轉為市場應用團隊,以加速活動。我們認為,這是因為網域小組的重點轉移,其網域產品的成功來自於其採用率。
我們發現了兩個同心回饋迴路,會影響採用率。外迴路是網域消費者(例如應用程式容器)良好的整合體驗。這是以開發人員為中心的回饋迴路,衡量標準是消費者可以多麼容易地設定和實作網域,作為其整體品牌特定產品的一部分。內迴路是良好的最終使用者體驗,整體歷程(包括整合的網域)受到消費者市場客戶的接受程度。不良的消費者體驗會影響採用率,並最終導致網域團隊與功能的實際使用者之間產生隔閡。我們發現,與消費者團隊密切合作且可以直接接觸最終使用者的網域團隊,擁有最快速的回饋迴路,因此最成功。
值得一提的最後一個比較,是來自於我們的平台網域。啟動新的網域功能是一項耗時的活動,會增加功能的整體開發成本。如前所述,平台團隊的目標是透過找出流程中的痛點並最佳化它們來減少這個時間,進而改善開發人員體驗。當我們將這個模型應用於模組化架構中的網域團隊時,我們發現每個團隊的啟動成本減少超過 80%。一對搭檔可以在一個下午完成原本估計需要團隊開發第一週才能完成的活動!
限制
到目前為止,您應該對模組化架構在行動裝置上的好處有相當樂觀的看法。但在對您有問題的單體應用程式大肆破壞之前,值得記住這些方法的限制。首先,而且確實最重要的是,像這樣的架構轉變「需要大量持續的時間和精力」。它只應被用來解決市場速度周圍嚴重的現有業務問題。其次,賦予領域團隊自主權既是一種祝福,也是一種詛咒。我們的平台小組可以提供常見的實作,形式為明智的預設值,但最終選擇權在於團隊本身。自然而然地,如果領域小組希望被納入/接受到市場應用程式中,那麼在平台需求(例如常見的 UI/UX)上達成共識符合他們的利益。然而,「管理來自類似內部依賴項或折衷設計模式的膨脹」很棘手。忽視這個問題並允許整體應用程式不受控制地增長,是導致客戶手中效能不佳的秘方。再次,我們發現對技術領導力的投資,加上強大的護欄和指南,有助於透過提供架構/設計監督、指導和最重要的溝通來減輕這個問題。
摘要
回顧一下,在本文開頭,我們找出了一個採用多應用程式策略的組織中出現的兩個重大交付問題。「將新功能導入生產的時間拉長」和「其他類似內部應用程式之間的特性差異越來越大」。我們證明了解決這些問題的方法不在於技術架構、團隊結構或技術負債的單一策略,而是在所有這些方面的同時演進複合體。我們首先展示了如何演進團隊結構以支援所需的模組化和以領域為中心的架構,如何改善認知和脈絡負載,同時讓團隊有自主權獨立於其他人開發。我們展示了這項工作的自然進展如何提升團隊和領域,使其與其原始應用程式/市場無關,以及這如何減輕康威定律對應用程式單體固有的影響。我們觀察到,這種變化允許消費者/供應商關係自然發生。我們進行的最後一個同步轉變是找出並投資於「平台」領域,以解決我們觀察到的因團隊和領域脫鉤而產生的核心問題。
將所有這些面向結合在一起,我們能夠在市場應用中所有模組化領域中平均展現縮減 60% 的週期時間。當將模組化領域整合至市場應用程式,而非從頭開始撰寫時,我們也看到開發成本改善了 18 倍。此外,由於新領域的啟動成本降低了 80%,以及「平台團隊」提供的持續支援,專注於工程效能讓我們的模組化架構蓬勃發展。對我們的客戶來說,這些節省實際上表示能夠利用市場機會,而這些機會以前被認為投資報酬率太低,不值得投入心力,這些機會多年來一直是競爭對手的無爭議領域。
關鍵重點是,與團隊內在連結的模組化架構在適當的情況下對組織極有幫助。雖然我們與強調的組織合作期間的成果極佳,但這些成果僅限於這個個別案例。花時間了解自己的環境,在採取行動前尋找跡象和反模式。此外,不要低估將我們所描述的生態系統結合在一起所需的前期和持續努力。考慮不周的努力很可能會造成的問題多於解決的問題。但是,透過接受你的情況在範圍上是獨特的,因此抵制「貨物崇拜」的吸引力:同時專注於同理心、自主性和溝通管道,讓架構發揮作用,那麼你有充分的理由複製我們所見的成功。
致謝
特別感謝 Carl Nygard、Tim Cochran 和 Greg Davis 提供的所有建議和重要回饋。也要感謝 Rob Horn 說服我整理思緒並實際撰寫這篇文章。最後,感謝 Martin Fowler 的指導。
重大修訂
2023 年 6 月 13 日:發布