當程式碼不管用時……問題起於團隊如何被組織,以及人們如何互動。

——艾瑞克・艾凡斯(Eric Evans),《領域驅動設計》

邊界決定流動#

當每個團隊都依賴一張與許多其他團隊互動的複雜網絡時,流動就難以達成。要讓變更快速流過軟體系統,我們必須移除交接,並讓多數團隊對齊到組織內主要的變更流。

然而,許多組織在「指派給團隊的職責邊界」上遭遇巨大問題。典型的情況是:幾乎沒有人思考過這些團隊邊界的可行性,結果就是擁有權缺失、投入度低落,以及冰川般緩慢的交付速度

本章定義並探討如何在軟體系統之內與之間,找出合適的邊界,讓團隊能以鼓勵流動的方式,有效且可持續地擁有並演化系統中屬於自己的部分。這些技術對單體軟體與已較鬆散耦合的軟體同樣適用。

關鍵在於,這些邊界是「團隊大小」的:我們把軟體與系統邊界對齊到單一團隊的能力,這立刻讓「擁有軟體」與「可持續地演化軟體」變得可行得多。

藉由審慎探索並驗證團隊之間的職責邊界——並運用領域驅動設計與斷層面等技術——我們讓軟體架構與問題領域對齊,提升變更的流動,並賦予組織「更快、更有效地演化社會技術系統」的能力。

軟體職責與邊界的團隊優先取徑#

軟體交付的許多問題,來自不同團隊及其職責之間意外地不清晰的邊界。如康威定律所言,這通常伴隨著一套「各部分之間高度耦合」的軟體架構——即使紙面上這套架構本該高度模組化且可擴充。這樣的系統通常被稱為「單體」(monolith)。

《Accelerate》發表的研究證實,緊密耦合的架構會負面影響「擁有清晰職責之自主團隊」的可能性。作者也提到有助於解耦的架構取徑:「能促成此策略[支撐團隊從設計到部署的完整擁有權]的架構取徑,包括使用限界上下文(bounded context)與 API,作為把大型領域解耦成更小、更鬆散耦合單元的方式。」

但當我們想從單體系統移向更鬆散耦合的服務時,也必須考慮新架構會如何影響涉入的團隊:他們的認知容量、所在位置,以及他們對新服務的興趣。

若不把團隊這個角度納入考量,我們就有可能在錯誤的地方拆分單體,甚至造出一套彼此依賴的複雜服務系統。

這種結果被稱為「分散式單體」(distributed monolith):團隊對自己的服務缺乏自主權,因為幾乎所有變更都需要同時更新其他服務。

Amazon 的服務團隊(第 4 章)這類例子顯示:我們必須思考並引導團隊互動,才能達成所欲的服務獨立性。

隱藏的單體與耦合#

單體軟體有很多種,其中有些一開始很難察覺。例如,許多組織花費時間心力把應用單體拆成較小的服務,結果卻在部署管線的下游產出一個單體式的發布,白白浪費了跑得更快更安全的機會。

在開始做任何變更之前,我們必須充分意識到自己正在面對哪一類單體。

應用單體#

一個龐大的單一應用,帶著眾多依賴與職責,可能對外暴露許多服務與/或不同的使用者旅程。這類應用通常整包部署,經常同時讓使用者頭痛(部署期間應用不可用)與運維者頭痛(因為正式環境是個移動標靶,即使我們在類正式環境測過單體,環境自那時起也必然已經漂移了)。

資料庫相連的單體#

由數個應用或服務組成,但全部耦合到同一個資料庫綱要,使它們難以分別變更、測試與部署。

這種單體常源於組織把資料庫(而非服務)視為核心業務引擎。

常見的情況是:一或多個 DBA 團隊被設立,不只要維護資料庫,還要協調資料庫的變更——而這往往是他們人力不足的任務——於是他們成了交付上的巨大瓶頸。

單體式建置(重建一切)#

用一個巨大的持續整合(CI)建置來取得某個元件的新版本。應用單體會導致單體式建置;但即使服務較小,建置腳本仍可能設定成建置整個程式碼庫,而不是使用元件之間的標準依賴管理機制(如套件或容器)。

單體式(耦合的)發布#

把一組較小的元件綁在一起成為一個「發布」。

當元件或服務可以在 CI 中獨立建置,卻只能在一個沒有服務模擬(mock)的共享靜態環境中測試時,人們最後會把所有元件的最新版本都搬進同一個環境,然後整組一起部署——因為這讓他們確信「測的就是將要上線的」。

有時這種做法也源於「有一個獨立 QA 團隊負責測試不同元件」——從一個產能有限的 QA 團隊的角度看,把多個服務變更批次化是合理的。

單體式模型(世界的單一視圖)#

軟體試圖在許多不同的上下文中強加單一領域語言與表述(格式)

在小型組織中偏好這種一致性或許合理(且僅在團隊明確同意這是好主意時);但一旦組織的團隊與/或領域數量超過寥寥數個,這種取徑就會不知不覺開始對架構與實作施加限制。

單體式思維(標準化)#

對團隊採取「一體適用」的思維,導致對團隊之間的技術與實作取徑施加不必要的限制。

把一切標準化以最小化差異,確實簡化了管理層對工程團隊的監督,但代價高昂。

好的工程師有能力也渴望學習新技術。強制單一技術堆疊與/或工具、剝奪團隊的選擇自由,會嚴重損害他們「用對的工具做對的事」的能力,並削弱(有時是殺死)他們的動機。

《Accelerate》的作者提到,他們的研究指出:對團隊強制標準化實際上減少了學習與實驗,導致更差的解法選擇。

單體式工作場所(開放式辦公室)#

在同一地理位置上,對所有團隊與個人採用單一辦公室配置樣式——通常是隔離的個人工作間(cubicle),或人與人桌位之間沒有明確屏障的開放式配置。

「辦公室該有標準化配置」的想法相當普遍。這也許簡化了營造承包商的工作,但可能對個人與團隊造成反覆的負面影響。

「開放式辦公室能增加協作」這個常見信念,已被一項田野研究所質疑:在兩個採用開放式辦公室的組織中,「面對面互動量顯著下降(約 70%)……並伴隨電子互動的增加」。

依作者經驗,這種情況發生在人們誤解了一件事:需要的是「目的的共處」,而不只是「身體的共處」。

軟體邊界,或稱「斷層面」#

每一種單體都帶來某些劣勢;但在團隊之間拆分軟體時,也有需要警覺的危險:

  • 拆分可能降低軟體不同部分之間的一致性
  • 可能導致跨多個子系統的意外資料重複
  • 若不小心維持連貫的 UX,跨多個部分的使用者體驗可能劣化
  • 若把軟體拆成更分散的系統,可能引入額外的複雜度

首先必須理解什麼是斷層面(fracture plane):斷層面是軟體系統中一道自然的接縫,讓系統能被輕易切成兩個以上的部分。

monolith 一詞源自希臘文,意為「單一石塊」。傳統石匠會以特定角度敲擊石塊,利用其天然的斷層面把岩石切成乾淨的區塊。我們可以在軟體中尋找類似的斷層面,找出通往軟體邊界的自然切點。

通常最好是設法讓軟體邊界與不同的業務領域區塊對齊。一個單體從技術角度看已經夠麻煩了(尤其是隨著建置、測試與修錯越來越耗時,它會逐年拖慢價值交付);若這個單體還同時驅動著多個業務領域區塊,那就是災難的配方,會同時影響優先排序、工作流動與使用者體驗。

然而,軟體的斷層面不只業務領域一種。我們可以、也應該組合不同類型的斷層面來拆解單體。

斷層面:業務領域限界上下文#

我們大多數的斷層面(軟體職責邊界)都應當映射到業務領域限界上下文

限界上下文是把較大的領域(或系統)模型切分成較小部分的單位,每個部分代表一個內部一致的業務領域區塊(此術語由艾凡斯在《領域驅動設計》中提出)。

福勒(Martin Fowler)解釋了限界上下文為何必須擁有內部一致的領域模型:

DDD[領域驅動設計]談的是依據底層領域的模型來設計軟體。模型作為一種通用語言(ubiquitous language),幫助軟體開發者與領域專家之間的溝通;它同時也是軟體本身設計的概念基礎——它如何被分解成物件或函式。要有效,模型必須是統一的——也就是內部一致,其中不存在矛盾。

DDD 專家圖恩(Nick Tune)與米列特(Scott Millett)在《Designing Autonomous Teams and Services》中舉了一個線上音樂串流服務的例子,其三個子領域與業務區塊良好對齊:媒體探索(尋找新音樂)、媒體遞送(串流給聽眾)、授權(權利管理、版稅支付等)。

辨識限界上下文需要相當程度的業務知識與技術專業,因此一開始犯錯是正常的。但這不該阻止你在更理解自身脈絡後去改善與調適,即使那意味著某種反覆出現的「服務重新設計成本」。

我們的設計中往往存在某種程度的語義耦合。用尼加德(Michael Nygard)的話說:「一個概念看起來之所以像是原子性的,可能只是因為我們用單一個詞去涵蓋它。看得夠仔細,你就會找到能把那個概念裂開的接縫。」換句話說,依限界上下文拆解系統時,應當預期一種逐步蠶食式的演化。

套用 DDD 的其他優點還包括:

  • 聚焦於特定業務領域之限界上下文內的核心複雜度與機會
  • 透過與業務專家的協作探索模型(因為現在要思考的領域變小了)
  • 建造能明確表達這些模型的軟體
  • 讓業務擁有者與技術人員在限界上下文內講同一套通用語言

總結:業務領域斷層面讓技術與業務對齊,減少術語不匹配與「翻譯中遺失」的問題,改善變更流動並減少返工。

斷層面:法規遵循#

在金融或醫療這類高度受監管的產業,法規要求往往能為軟體提供硬性邊界。它們常要求組織對「落入該法規範圍內」的軟體採用特定的稽核、文件、測試與部署機制,無論是信用卡支付、交易申報等。

  • 一方面,把這些流程在不同系統間的差異最小化是好主意。但要確保這些流程(包括人工核准或活動)始終被映射進交付管線,並對管線設有適當存取控制,如此便能在涵蓋多數稽核要求的同時,取得跨所有系統的變更可追溯性。
  • 另一方面,不該把嚴格要求強加於系統中沒那麼關鍵的區域。把落入法規範圍的子系統或流程從單體中切出來,是一道自然的斷層面。

例如,支付卡產業資料安全標準(PCI DSS)訂立了一組關於請求與儲存信用卡資料的規則。PCI DSS 的遵循應當落在一個專責的卡片資料管理子系統上,而不該把這些要求套用到「碰巧包含支付功能」的整個單體。

沿法規遵循斷層面拆分,能簡化稽核與法遵,並縮小法規監理的波及半徑

最後,這裡還牽涉團隊組成與互動的面向,在較大型組織中尤其如此:當單一大團隊負責整個單體時,法遵與/或法務團隊的人通常只偶爾參與規劃與優先排序會議,因為工作範疇不足以支撐這些關係人的全職團隊成員身分。而當該子系統被切出來後,成立一個規模較小但聚焦法遵的團隊(納入來自法遵與/或法務領域的業務擁有者)就突然變得合理許多。

斷層面:變更節奏#

另一道自然斷層面,出現在系統不同部分需要以不同頻率變更之處。

在單體中,每一塊都以最慢那塊的速度移動

若新的報表功能只需每季發布一次,那麼要讓其他類型的功能以更高頻率發布,很可能會變得極為困難甚至不可能——因為程式碼庫始終處於變動中、隨時無法上線。變更被混在一起,交付速度嚴重受害。

把「通常以不同速度變更」的部分切出來,能讓它們變得更快。如此一來,驅動變更速度的是業務需要,而不是由單體對所有東西強加一個固定速度。

斷層面:團隊位置#

跨地理與跨時區分散的團隊顯然沒有共處一地。但即使成員在同一棟辦公大樓、只是分屬不同樓層或不同實體空間,也可以視為地理上分離。

在分散式團隊中,溝通受限,因為他們必須明確地為跨地點溝通申請實體或虛擬的空間與時間。其餘(未經規劃的)團隊內溝通——比例可高達 80%——則發生在團隊各個分部各自的實體邊界之內。

跨時區工作會加劇這些溝通延遲,並在「需要不同時區、工作時間幾乎不重疊的人提供人工核准或程式碼審查」時製造瓶頸。

海爾芬德(Heidi Helfand)在《Dynamic Reteaming》中強調時區差異的問題:「如果你必須有遠端工作者,你就得付出額外的工夫去培養團隊內與團隊間的協作,才能建立起社群。你應當設法讓大家在同一時區而非不同時區;否則人們會不想彼此開會,因為那侵蝕了他們在家的個人時間。」

作者主張,要讓團隊有效溝通,選項只有兩個:

  • 完全共處一地——所有成員共享同一實體空間
  • 真正的遠端優先——明確地把溝通限制在團隊每個人都能取用且會定期查看的約定管道(如訊息與協作應用)

當這兩個選項都不可行時,更好的做法是把單體拆成不同的子系統,分給不同地點的團隊。如此,組織便能善用康威定律,讓系統架構與現實中的溝通限制對齊。

斷層面:風險#

一個大型單體裡可能並存著不同的風險輪廓。承擔更多風險,意味著接受更高的系統或成果失敗機率,以換取更快把變更送到顧客手上。

附帶一提:在鬆散耦合的系統架構(而非單體)上具備真正的持續交付能力,實際上降低了「非常頻繁地部署小變更」的風險。

有多種風險類型(通常對應到業務對變更的胃納)可以提示出斷層面:

  • 法規遵循是一種特定風險類型(前已述及)
  • 行銷驅動的變更風險輪廓較高(聚焦於顧客獲取)vs. 創造營收的交易功能變更風險輪廓較低(聚焦於顧客留存)
  • 使用者數量也可能驅動可接受的風險。例如一個多層級 SaaS 產品,免費層可能有數百萬使用者,付費層卻只有數百家客戶。免費層熱門功能的變更可能落入較高風險輪廓,因為任何重大失敗都可能意味著失去數百萬潛在付費客戶;而僅付費功能的變更或許實際上承擔較少風險——如果對那數百家客戶的支援速度與個人化程度足以彌補偶發的失敗
  • 基於類似理由,組織的內部系統通常能承受較高的風險輪廓(不過這不代表它們就不該被當作正規產品對待,即使僅供內部使用)

把風險輪廓明顯不同的子系統切出來,能讓技術變更映射到業務胃納或法規需要;也讓每個子系統得以隨時間演化出自己的風險輪廓,採用持續交付這類「能在不增加風險的前提下提升變更速度」的實踐。

斷層面:效能隔離#

在特定類型的系統中,區分不同的效能層級可能有益。當然,效能對每個系統都該是關切點,也應當被分析、測試並在可能處最佳化。

然而,應用中那些會遭遇大規模需求尖峰的部分(例如年度報稅的最後一天),需要的擴展與容錯最佳化程度,是系統其餘部分不需要的。

依特定效能需求把這類子系統切出來,有助於確保它能自主擴展,提升效能並降低成本。

例如,一個完整的報稅應用可以由「效能關鍵、能在短時間內處理數百萬份申報」的申報與驗證子系統,加上稅務試算、處理與繳款等效能要求較不關鍵的子系統所組成。

斷層面:技術#

(歷史上)技術往往是拆分團隊時唯一使用的邊界類型。想想「前端團隊、後端團隊、資料層團隊各自分立」有多常見。

然而,這類常見的技術驅動拆分,通常引入更多限制、降低而非提升工作流動。

原因是:這些分立團隊的自主性更低——產品依賴依然存在,而每個團隊對整體工作的能見度更低,且團隊間的溝通路徑比團隊內慢。

確實存在「依技術拆分子系統會有效」的情況,特別是那些整合了較老舊或較難自動化之技術的系統:

  • 涉及這類老舊技術的變更,流動會相當慢——可能因為必須跑更多手動測試,或因為文件不良、缺乏開放而支持性的使用者社群(這在現代技術堆疊是理所當然的)而難以實作變更
  • 這類技術周邊的工具生態系(IDE、建置工具、測試工具等)在行為與感受上都與現代生態系大不相同,提高了需要在這些迥異技術之間切換之成員的認知負荷

在決定是否沿技術斷層面拆分之前,先調查有沒有其他做法能提升老舊技術的變更步調——那能移除限制、對業務有利(同時仍讓單體沿「業務對齊的限界上下文」這類更有價值的斷層面拆分)。

例如,赫林(Mirco Hering)在《DevOps for the Modern Enterprise》中說明了如何在面對專有 COTS 產品時,套用良好的編碼與版本控制實踐。

斷層面:使用者輪廓#

隨著系統成長、功能集擴張,其客戶群(內部或外部)也隨之成長與分化。某些使用者群體會倚賴某一組功能完成工作,另一些群體則需要另一組:

  • 在分層定價的產品中,這種子集是設計出來的(付費較高的客戶能存取比低付費或不付費客戶更多的功能)
  • 在其他系統中,管理員使用者能存取比一般使用者更多的選項與控制
  • 或者單純地,經驗豐富的使用者比新手更常使用某些功能(例如鍵盤快捷鍵)

因此在這類情境下,依使用者輪廓切出子系統是合理的。

移除功能之間依賴或耦合所需的心力,會由「對顧客需要與使用體驗更銳利的聚焦」所補償,而那應當帶來更高的顧客滿意度並改善組織的獲利。

事實上,這種結構也能提升客戶支援的速度與品質——把問題映射到特定子系統與團隊變得更容易。負責「與企業級輪廓對齊之子系統」的團隊,或許會希望確保隨時有人能盡可能順暢地處理(企業級的)支援問題。

為你的組織或技術找出專屬的自然斷層面#

有時還能辨識出其他自然的、可用的團隊優先斷層面來分派工作。

「產生出來的架構,是否支撐了更自主的團隊(依賴更少)與更低的認知負荷(職責更不分散)?」

當然,要達成這樣的結果通常需要一些初步實驗與微調,不真的認真試一次,就不太可能保證某個特定結果。

有個簡單的啟發法可以幫助評估你的系統與團隊邊界,就問:

我們作為一個團隊,能否有效地把這個子系統當作服務來消費、或提供出去?

若答案是肯定的,那這個子系統就是「切出來、指派給一個團隊去擁有並演化」的好候選。

案例研究:Poppulo 如何找到好的軟體邊界

——薛翰(Stephanie Sheehan),Poppulo 營運副總;戴利(Damien Daly),Poppulo 工程總監

Poppulo 讓組織能在同一處規劃、鎖定、發布並衡量其跨多重數位通路之溝通的成效。2012 年起的四年間,我們規模成長三倍、在美國開設辦公室,並累積了包含 Nestlé、Experian、LinkedIn、Honda、Rolls-Royce 等全球頂尖品牌的龐大客戶組合。截至 2019 年,Poppulo 平台被超過一百個國家、逾 1,500 萬名員工使用。走到這一步,我們必須在三年間從單一開發團隊擴展到八個產品團隊、一個 SRE 團隊與一個基礎設施團隊。

起點(2015 年):我們預期客戶群與工程人力都將顯著成長,因此希望以「能讓新團隊大體獨立自主」的方式拆分單體。隨著我們招募更多工程師,那套「單一團隊行得通」的架構與實踐已無法擴展。我們把 DevOps 與持續交付實踐放在設計選擇的核心,並開始從既有的(成功的)單體系統轉向微服務型架構。

先從「團隊」開始:我們先是更強烈地聚焦於「團隊」作為完成工作的手段。過去我們有時會出現繞著個人打轉的瓶頸;但採取團隊取徑、導入結對(後來還有群體編程)等實踐後,我們開始看到更好的工作流動,因為成員會互相幫忙完成任務。

再建立能見度:接著我們開始為程式碼加裝儀表與遙測,好讓我們看得見程式碼在正式環境中實際如何運作。搭配端到端部署管線,改善後的日誌與指標讓團隊更理解程式碼,並開始承擔擁有權。

依領域邊界拆分:Poppulo 的產品幫助組織以電子方式與大量人群溝通,因此我們的業務領域圍繞著人員、內容、活動、電子郵件、行動、分析等概念。我們從閱讀與研討會演講中知道「透過乾淨的領域分離,賦予交付團隊對齊的自主性」有多重要。因此我們花了一段時間評估每個領域究竟有多獨立,並在白板上推演各種情境,然後才沿這些領域邊界拆分軟體。我們很在意不要被康威定律過度反噬,所以確保領域分離確實有效至關重要。

團隊組織:我們重視協作與自主,因此把自己組織成「矩陣式產品團隊」——跨職能、坐在一起、完整擁有產品某個領域的團隊。我們的產品團隊通常由四名開發者、一名生產經理、一名 QA、一名 UX/UI 設計師組成。團隊直接與顧客和關係人對話:他們旁聽支援電話;他們設計、建造並衡量自己解法的影響;他們對自己交付之解法的品質負責。

方法與工具:我們運用一些 DDD 技術,特別是事件風暴(event storming),來理解並建模業務脈絡中的領域。在較技術的層面,我們使用 Pact 做服務的契約測試與跨團隊溝通。Pact 確實幫助我們建立了清晰、明確的服務測試取徑,並在所有團隊之間設定了「如何測試、如何與其他團隊互動」的期待。

團隊與斷層面的對應

  • 多數交付團隊對齊到業務領域限界上下文,例如電子郵件、行事曆、人員、問卷等
  • 也有少數系統部分對齊到法規邊界(特別是資訊安全管理的 ISO 27001),以及跨領域的功能使用回報需求;這些領域由一支小型專業團隊或跨數個團隊的協作處理
  • 另有一支團隊協助在軟體所有部分提供一致的使用者體驗;UX 團隊扮演所有交付團隊的內部顧問,讓他們能快速採用良好 UX 實踐
  • 我們運行 SRE 能力,以處理高流量並增強可運作性

成果:花時間理解業務領域、並把單體軟體拆分到與領域相符,幫助我們自 2015 年起把工程部門從 16 人擴展到 70 人。投資於遙測與良好的維運焦點,幫助團隊理解他們正在建造的軟體。透過採用具備我們所稱「對齊的自主性」的跨職能產品團隊,我們看到團隊內對軟體服務有良好的擁有權,這反過來讓我們能在最小化停機的同時保持快速的變更流動。

真實世界案例:製造業#

前面談技術作為斷層面時,我們強調這應當謹慎使用,且多半用於那些在感受與行為上都與現代軟體堆疊差異甚大的老舊技術。但你難免會遇到例外。困難之處在於判斷:何時例外是站得住腳的,何時那條「快速取得進展的捷徑」最終反而限制了成效。

案例:IoT 消費裝置製造商的三種技術堆疊

作者曾服務過一家相當大的製造業客戶,生產面向消費者的實體裝置。所有裝置都具備 IoT 能力,包括從行動 App 遠端控制,以及透過雲端遠端軟體更新。裝置同時受雲端(排程活動)與互動式使用者操作(行動 App)控制。所有活動日誌與產品資料都送往雲端處理、過濾與儲存。

為什麼一個流動對齊團隊扛不起來:考慮到本書前面強調的規模與認知負荷限制,要讓一個流動對齊團隊擁有整個端到端使用者體驗——行動 App、雲端處理、裝置的嵌入式軟體——會極其困難。橫跨三種截然不同的技術堆疊(嵌入式、雲端、行動)做端到端變更,所需的技能組合難以尋覓,而隨之而來的認知負荷與情境切換將難以承受。最好的情況是變更在技術與架構上不夠理想;最壞的情況是變更脆弱、技術債穩定累積,並且整體上給顧客糟糕的使用者體驗。

做法:接受技術限制——團隊可以沿自然的技術邊界組織(嵌入式團隊、雲端團隊,也許還有行動團隊)。這些技術之間的落差(在技能與部署速度上)為各自施加了不同的變更步調,而那正是分立團隊的關鍵驅動因子

圖 6.1:行動、雲端與 IoT 的技術斷層面情境——面對三種差異極大的技術(行動、雲端、IoT),組織必須依各領域的認知負荷與變更節奏,決定一套合理的斷層面取徑。

兩個主要選項

  1. 把雲端軟體當作平台,行動與嵌入式 IoT 軟體則是該平台的客戶端/消費者。若消費端 App 的變更速率或變更容易度至少與雲端平台的變更一樣快,這會運作良好。
  2. 把嵌入式 IoT 裝置當作平台,讓雲端與行動 App 成為該平台的客戶端/消費者。

兩種模型都行得通,但無論哪一種,扮演平台角色的團隊都必須採用平台式的取徑

代價與長期效益:這種取徑會要求團隊之間為「影響兩個以上技術領域的功能」定期協調——例如可能需要先排定雲端平台 API 的變更,新軟體版本才能部署到嵌入式裝置。不過,這種協調也應當有助於在團隊之間建立共通的工作方式(如語意化版本、日誌取徑、API 優先開發)。

長期下來,隨著各技術的變更步調趨於相近,這些共享的實踐與知識,可能讓未來重新調整團隊邊界成為可能。

本章總結:選擇能匹配團隊認知負荷的軟體邊界#

為流動最佳化時,流動對齊團隊應當負責單一領域。當領域被藏在「包含許多不同職責、主要由技術選擇所驅動、橫跨多個業務區塊提供功能」的單體系統裡時,這就成了一項挑戰。

我們需要尋找拆解系統的自然方式(斷層面),讓拆出來的各部分能盡可能獨立地演化。如此一來,被指派到那些部分的團隊,就會擁有更高的自主性與擁有權。

  • 設法讓子系統邊界與(大體獨立的)業務區塊對齊是很好的取徑,而領域驅動設計方法論恰好很好地支撐這個取徑。
  • 但我們也必須警覺並感知其他斷層面:變更節奏、風險、法規遵循等。通常需要多種斷層面的組合。

我們還必須意識到各種阻礙流動、並在團隊之間製造不必要依賴的單體類型。我們通常把系統架構想成單體,但耦合還有其他更隱微的滲入方式,即使系統架構已經模組化亦然(例如共享資料庫、耦合的建置與/或發布等)。誠如菲利普斯(Amy Phillips)所說:

「如果你有微服務,卻要等到發布前才把它們組合起來做端到端測試,那你擁有的其實是一個分散式單體。」

在考慮子系統邊界時,主要目標應當是找出與業務領域限界上下文對齊的軟體斷層面,因為多數限界上下文會映射到組織中自然存在的變更流。這反過來意味著業務領域邊界可以對齊到流動對齊團隊,幫助整個組織聚焦於流動。

斷層面也可以圍繞特定挑戰來選擇(技術、法規、效能、人員地理位置、使用者輪廓),以幫助避免團隊之間的交接並促進流動。

在所有情況下,關鍵都是把軟體切成團隊大小的段落,好讓團隊能以可持續的方式有效擁有並演化自己的軟體。