軟件架構(gòu)與實驗的藝術(shù)
作者:Pierre Pureur, Kurt Bittner
2025-01-02
要點
- 談到軟件架構(gòu)矾芙,犯錯是不可避免的。架構(gòu)設(shè)計的藝術(shù)在于試錯的時候只用一點時間永毅。做出決定的唯一方法是進行實驗并收集可以為這些決策提供信息的數(shù)據(jù)委刘。
- 最小可行架構(gòu)(MVA)由測試架構(gòu)決策可行性的一些實驗組成丧没。這些實驗收集反饋,使開發(fā)團隊能夠修改他們的決策锡移。
- MVA 也是關(guān)于其 MVP 的實驗呕童;它們從技術(shù)角度測試 MVP 的可行性。如果 MVP 在技術(shù)上不可行淆珊,那么 MVP 就沒有業(yè)務(wù)價值夺饲。
- 實驗不止是要嘗試某種東西,看看它是否有效施符。每個產(chǎn)品版本都是一組關(guān)于價值和可支持性的實驗往声。這些實驗的反饋有助于開發(fā)團隊提高產(chǎn)品的價值和可支持性。
- 架構(gòu)實驗還需要預(yù)測“支持和更改”方面的工作戳吝。
犯錯令人沮喪浩销、浪費資源,有時會讓人很尷尬听哭,但……這是不可避免的慢洋。尤其是在軟件架構(gòu)方面,如果你從不犯錯陆盘,意味著你就沒充分挑戰(zhàn)自我普筹,也沒有學(xué)到東西。但犯錯在心理上太痛苦了隘马,所以大多數(shù)人都會避免犯錯太防,主要的逃避方式就是從不檢查他們的工作。
有些人認為酸员,如果不構(gòu)建出整個軟件產(chǎn)品蜒车,他們就無法測試其架構(gòu)。但軟件架構(gòu)不是一個單一的東西沸呐,它是許多決策的結(jié)果醇王,其中每個決策都可以通過實驗進行分離和評估。
雖然我們有時無法避免犯錯崭添,但我們可以通過運行很多小實驗來測試我們的假設(shè)寓娩,并在錯誤決策的成本增加之前扭轉(zhuǎn)它們,從而降低犯錯的成本呼渣。但時間是我們的敵人:你永遠沒有足夠的時間來測試每一個假設(shè)棘伴,因此搞清楚我們要面對哪些假設(shè)就是架構(gòu)設(shè)計的藝術(shù)。
成功的架構(gòu)設(shè)計意味著通過實驗來測試影響系統(tǒng)架構(gòu)的決策屁置,即那些如果你犯錯就會對你所構(gòu)建的東西的成功造成“致命”影響的決策焊夸。
知道要測試什么只是問題的一半;另一半是設(shè)計有效但低成本的實驗蓝角,以揭示假設(shè)中的缺陷阱穗。
這是我們稱之為最小可行架構(gòu) (MVA) 的概念背后的關(guān)鍵思想饭冬,它是一組決策,你認為這些決策將使系統(tǒng)或產(chǎn)品的增量揪阶,即最小可行產(chǎn)品 (MVP)昌抠,能夠隨著時間的推移持續(xù)提供價值。
在本文中鲁僚,我們探討了良好實驗的屬性炊苫。
MVA 是測試架構(gòu)決策可行性的實驗
在前文中,我們觀察到:
了解這些決策是否合理的唯一方法是進行實驗和收集數(shù)據(jù)冰沙。這些實驗會測試 MVP 的可負擔(dān)性侨艾、可行性、可持續(xù)性和可支持性拓挥。MVA 反映了開發(fā)團隊為實現(xiàn) MVP 的架構(gòu)目標而做出的種種權(quán)衡唠梨。由于每個版本都是具有相關(guān) MVA 的 MVP,因此每個版本都是一組關(guān)于價值和可支持性的實驗撞叽。發(fā)布新版本的目的是向客戶提供價值姻成,并收集有關(guān)版本在多大程度上滿足了客戶需求的反饋,包括當(dāng)前和系統(tǒng)的整個生命周期內(nèi)的情況愿棋。
如果團隊不進行架構(gòu)實驗科展,那么他們的決策就只是基于各種假設(shè)來猜測解決方案到底需要什么內(nèi)容。如果猜測被證明是錯誤的糠雨,那么由于其影響才睹,逆轉(zhuǎn)它們的代價將非常高昂,甚至可能扼殺產(chǎn)品 / 項目甘邀。
例如琅攘,團隊可能決定使用矢量數(shù)據(jù)庫,使用機器學(xué)習(xí)技術(shù)為金融機構(gòu)開發(fā)專有的欺詐檢測服務(wù)松邪。根據(jù)他們的研究坞琴,使用某種向量數(shù)據(jù)庫產(chǎn)品可能會加快 MVP 的開發(fā),而其中一名團隊成員對該產(chǎn)品的經(jīng)驗有限逗抑。作為一項實驗剧辐,他們決定使用該產(chǎn)品實現(xiàn)一個小型欺詐檢測用例,并衡量生產(chǎn)率的提升幅度邮府。
然而荧关,事實證明,預(yù)期的生產(chǎn)率提升并未實現(xiàn)褂傀,因為該產(chǎn)品比預(yù)期的要難得多忍啤。向量數(shù)據(jù)庫的編程接口與團隊選擇的編程范式不匹配,使用該產(chǎn)品實現(xiàn)性能目標也很有挑戰(zhàn)性仙辟。根據(jù)他們的實驗同波,團隊意識到使用向量數(shù)據(jù)庫會延遲甚至可能威脅到 MVP 的交付鳄梅,因此他們決定不使用該產(chǎn)品。
MVA 也是測試 MVP 技術(shù)可行性的實驗
可以這樣理解 MVA参萄,它由一個或多個實驗組成卫枝,用于測試產(chǎn)品增量或 MVP 所提供價值的長期可持續(xù)性。正如我們在上一篇文章中所觀察到的讹挎,最小可行產(chǎn)品(MVP)的概念可以幫助團隊盡早專注于提供他們認為對客戶最有價值的產(chǎn)品,這樣他們就可以在投入大量時間和資源之前快速且廉價地評估其產(chǎn)品的市場規(guī)模吆玖。因此筒溃,每個 MVP 都是一組實驗,用于測試產(chǎn)品增量為客戶帶來的價值沾乘。
MVA 很重要怜奖,因為 MVP 只是障眼法(或一廂情愿的想法),除非你擁有可以支持它的 MVA翅阵。我們已經(jīng)目睹了許多例子歪玲,其中業(yè)務(wù)利益相關(guān)者提出了大膽的業(yè)務(wù)創(chuàng)新,但并未考慮如何或是否可以實現(xiàn)該想法掷匠。
MVP 不僅限于初創(chuàng)企業(yè)滥崩,因為每個應(yīng)用程序都有一個可以視為 MVP 的初始版本。MVP 是產(chǎn)品開發(fā)戰(zhàn)略的一個有用組成部分讹语。與單純的原型不同钙皮,MVP 并非簡單地以“丟棄”為目標。
我們談?wù)?MVA 的方式有時會讓人覺得它們是與 MVP 分開的實驗顽决,但事實并非如此短条,正如我們在之前的一篇文章中所討論的那樣。當(dāng)開發(fā)團隊致力于他們的 MVP 時才菠,他們會不斷做出關(guān)于產(chǎn)品如何實現(xiàn)其架構(gòu)目標的架構(gòu)決策茸时。這些決策就是 MVA。
有效架構(gòu)實驗的特征
實驗不僅是要嘗試某件事以查看它是否有效赋访;它是一種專門用于確認或拒絕特定假設(shè)的測試可都。假設(shè)是團隊對其解決方案適用性所提出的問題的潛在答案。實驗無法證明某件事是正確的进每,只能證明某件事是錯誤的汹粤,但這仍然很有用,因為這意味著如果你正確設(shè)計實驗田晚,就可以判斷哪些假設(shè)是錯誤的——在它們引起不愉快的意外之前嘱兼。
如果你不進行實驗,意味著你會假設(shè)你已經(jīng)知道了某些問題的答案贤徒。只要情況真的如此芹壕,或者只要出錯的風(fēng)險和成本很小汇四,你可能就不需要進行實驗。然而踢涌,一些大問題只能通過實驗來回答通孽。由于你可能無法對所有必須回答的問題都進行實驗,意味著你會隱式地接受相關(guān)風(fēng)險睁壁,因此你需要在可以進行的實驗數(shù)量和無法通過實驗減輕的風(fēng)險之間做出權(quán)衡背苦。
創(chuàng)建測試 MVP 和 MVA 的實驗的挑戰(zhàn)在于提出挑戰(zhàn)利益相關(guān)者和開發(fā)人員的業(yè)務(wù)和技術(shù)假設(shè)的問題。這些實驗必須足夠小潘明,以便快速收集反饋行剂,但又足夠重要,以應(yīng)對團隊面臨的風(fēng)險钳降。
在 MVA 的語境下厚宰,這意味著要面對團隊正在做出的架構(gòu)決策可能被證明是錯誤的風(fēng)險。團隊執(zhí)行這一流程是遂填,首先要問自己:“我們做出的哪些決策如果被證明是錯誤的铲觉,將最具破壞性”和“哪些事件更有可能發(fā)生”。我們發(fā)現(xiàn)這種討論很有用吓坚,但不需要很長撵幽;大多數(shù)團隊都很清楚哪些決策讓他們夜不能寐。
正如我們在 另一篇文章 中指出的那樣凌唬,每個需求并齐,包括驅(qū)動架構(gòu)設(shè)計的質(zhì)量屬性需求(QAR),都代表著一個關(guān)于價值的假設(shè)客税。明確這些假設(shè)并有意識地設(shè)計實驗有助于團隊避免對其解決方案做出很多假設(shè)况褪。
有效的架構(gòu)實驗是:
- 原子的。它們一次處理一個問題更耻。同時進行多個實驗會使結(jié)果混亂测垛,并且往往會讓重要的反饋來得更慢。
- 及時秧均。它們將風(fēng)險分解成很多小的食侮、可管理的部分,以便更快獲得反饋并簡化結(jié)果的解釋目胡。
- 明確锯七。它們有明確的成功標準和可衡量的結(jié)果。實驗不是簡單地嘗試某件事來看看它是否有效誉己。
為了幫助實現(xiàn)這一點眉尸,每個實驗都需要:
- 一個明確的假設(shè)。為一家保險公司工作的團隊正在考慮使用圖像識別軟件來檢測火災(zāi)多發(fā)區(qū)的房屋在一定距離內(nèi)是否有植被。他們假設(shè)該軟件可以檢測植被并測量其與建筑物的距離噪猾,以使用從衛(wèi)星拍攝的圖像評估火災(zāi)風(fēng)險霉祸。
- 一個明確且可衡量的目標或指標。實驗的目標是確定圖像識別軟件是否可以使用清晰的高分辨率衛(wèi)星照片檢測和識別特定房屋 30 英尺范圍內(nèi)的兩棵灌木和一棵樹袱蜡。
- 運行實驗的方法和衡量其成功或失敗的機制丝蹭。由于實驗范圍有限,并將嘗試識別有明確定義的形狀坪蚁,因此它將使用預(yù)訓(xùn)練的圖像識別模型奔穿,該模型只需要有限的訓(xùn)練。實驗結(jié)果將對比房屋及其周圍環(huán)境的地面照片敏晤,以驗證模型的結(jié)果巫橄。
- 如果實驗失敗,則需要執(zhí)行回滾計劃茵典。對于上述示例,由于實驗是非破壞性的宾舅,不會改變現(xiàn)有數(shù)據(jù)的狀態(tài)或內(nèi)容统阿,因此不需要回滾計劃。在某些代碼更改的情況下筹我,如果實驗失敗扶平,就可能需要恢復(fù)到以前的代碼版本。在其他情況下蔬蕊,實驗必須在部署給客戶的版本中進行结澄。例如,如果實際使用反饋對于收集決策所需的數(shù)據(jù)至關(guān)重要岸夯,團隊就需要一種方法來使用 A/B 測試等技術(shù)來回滾更改麻献,或者在實驗失敗時快速重新部署系統(tǒng)。
- 實驗的明確時間表猜扮。由于我們的工作周期很短勉吻,因此實驗需要符合發(fā)布的時間限制。在 Scrum 等敏捷方法的背景下旅赢,實驗需要在一個 Sprint 內(nèi)完成齿桃。如果實驗太難在開發(fā)和測試發(fā)布的時間范圍內(nèi)完成,你必須將其分解為一些較小的實驗煮盼。
有時實驗無法達到預(yù)期結(jié)果短纵,團隊可能會傾向于延長實驗時間,以便有時間改進解決方案僵控。這應(yīng)該是一個新的實驗香到,而不是舊實驗的延伸。考慮上述圖像識別實驗的情況养渴。團隊可能會傾向于相信額外的模型訓(xùn)練可以改善結(jié)果并使實驗成功雷绢。但這應(yīng)該被視為一個單獨的實驗。
有些實驗可能需要團隊購買硬件或軟件理卑,聘請(即使只是暫時的)具有所需專業(yè)知識的人翘紊,或購買他們沒有的計算資源(如云或測試環(huán)境)。在這些情況下藐唠,他們可能需要預(yù)算和資金批準帆疟。
架構(gòu)回顧可以幫助團隊考慮他們是否做了足夠的實驗,或者可能做了太多的實驗宇立。不做實驗的問題很明顯踪宠,但做太多實驗也同樣糟糕;如果一個決定是否錯誤并不重要妈嘹,那么這個決定實際上不是架構(gòu)性的柳琢,而只是一種不同的設(shè)計選擇。
架構(gòu)實驗還需要預(yù)測“支持和變更”工作
我們很重視軟件系統(tǒng)中的模塊化润脸,因為它使系統(tǒng)更容易擴展和發(fā)展柬脸。但就像建筑物一樣,如果構(gòu)思或執(zhí)行不當(dāng)毙驯,對軟件系統(tǒng)的連續(xù)更改最終可能會壓垮系統(tǒng)并降低其長期可行性倒堕。良好的軟件架構(gòu)可以預(yù)測變化,并使某些類型的變化更容易爆价、破壞性更小垦巴。但團隊如何知道在預(yù)測和緩解未來變化方面要投入多少資金?他們?nèi)绾沃浪麄冊谶@方面的工作是否成功铭段?
與其他類型的架構(gòu)決策一樣骤宣,唯一的方法是做一些實驗,重點評估某些類型變化的成本和影響稠项。例如涯雅,考慮一個保險承保系統(tǒng),該系統(tǒng)處理特定類型的承保資產(chǎn)(例如家用家具)和特定類型的損失事件(例如火災(zāi))展运。對于開發(fā)該系統(tǒng)的團隊來說活逆,一種很有用的方法是考慮添加一種新的受保資產(chǎn)(例如藝術(shù)品)和一種新的損失事件(例如盜竊)的難易程度。他們可能會發(fā)現(xiàn)某些類型的更改很容易拗胜,而其他類型的更改則需要全新的系統(tǒng)蔗候。
這是房主保險不涵蓋汽車的原因之一,因為解決索賠的風(fēng)險和決策標準差異太大埂软,一個系統(tǒng)無法適用于每種資產(chǎn)和每種風(fēng)險锈遥。了解變更的界限是一項重要的架構(gòu)決策纫事。
架構(gòu)工作還必須考慮系統(tǒng)將如何隨著時間的推移得到支持。當(dāng)它失敗時所灸,它是否提供了足夠的信息來診斷問題丽惶?回答這個問題需要了解支持人員的專業(yè)知識以及可能導(dǎo)致故障的事件類型。有時爬立,了解這一點的唯一方法是運行旨在導(dǎo)致系統(tǒng)失敗的實驗钾唬,以查看系統(tǒng)如何反應(yīng)以及在系統(tǒng)失敗后需要哪些信息來解決問題。
例如,保險公司的汽車保單系統(tǒng)通常會使用規(guī)則引擎為公司客戶定制保險并為其定價。配置和測試規(guī)則通常是一項具有挑戰(zhàn)性且耗時的任務(wù)条摸。正如 Thomas Betts 在最近的一篇文章中所建議的那樣,使用大型語言模型(LLM)輸入和驗證這些規(guī)則將是一種讓這項任務(wù)變得更容易和更快的好方法相赁,前提是保險公司有足夠的規(guī)則配置示例來訓(xùn)練 LLM。
然而,LLM 的輸出有時很難解釋,團隊應(yīng)該運行旨在讓 LLM 生成“錯誤”信息的實驗着撩,以確保如果在生產(chǎn)中發(fā)生這種情況,他們也能診斷出問題匾委。進行這種實驗可能會避免系統(tǒng)實施后出現(xiàn)一些令人不快的意外睹酌。如果他們無法診斷問題,這可能會說服團隊重新考慮他們基于 LLM 的方法剩檀。
總? ?結(jié)
軟件架構(gòu)工作并不總是可預(yù)測的;系統(tǒng)是復(fù)雜的實體旺芽,有時會以意想不到的方式運行沪猴。有時,了解預(yù)期行為和意外行為之間界限的唯一方法是做實驗采章。MVA 的目標之一是提供一種運行架構(gòu)實驗的機制运嗜,以便開發(fā)團隊能夠了解他們的架構(gòu)決策何時以及如何失敗。有了更好的信息悯舟,開發(fā)團隊可能會做出不同的選擇担租,或者至少知道他們的假設(shè)何時可能失敗。
當(dāng)超出系統(tǒng)限制的風(fēng)險很低時抵怎,開發(fā)團隊可能會決定接受風(fēng)險奋救,但即使在這些情況下,他們也應(yīng)該在設(shè)計系統(tǒng)時使其能夠優(yōu)雅地失敗反惕,并為支持人員或未來的開發(fā)團隊成員提供足夠的信息來解決問題尝艘,而不會因為解決方案而廢棄系統(tǒng)的主要部分。
在軟件架構(gòu)中姿染,有時出錯是不可避免的背亥;如果你從不犯錯,那你就沒有充分挑戰(zhàn)自我,也沒有學(xué)到東西狡汉。最重要的是盡可能多地用挑戰(zhàn)我們假設(shè)的實驗來測試我們的決定娄徊,并以這樣的方式構(gòu)建系統(tǒng),做到當(dāng)我們的決定不正確時盾戴,系統(tǒng)不會災(zāi)難性地失敗寄锐。
作者介紹
Pierre Pureur是一位經(jīng)驗豐富的軟件架構(gòu)師,擁有豐富的創(chuàng)新和應(yīng)用開發(fā)背景捻脖、廣泛的金融服務(wù)行業(yè)經(jīng)驗锐峭、廣泛的咨詢經(jīng)驗和全面的技術(shù)基礎(chǔ)設(shè)施知識。他過去的職位包括擔(dān)任一家大型金融服務(wù)公司的首席企業(yè)架構(gòu)師可婶、領(lǐng)導(dǎo)大型架構(gòu)團隊沿癞、管理大型并發(fā)應(yīng)用開發(fā)項目和指導(dǎo)創(chuàng)新計劃,以及制定戰(zhàn)略和業(yè)務(wù)計劃矛渴。他是《實踐中的持續(xù)架構(gòu):敏捷和 DevOps 時代的可擴展軟件架構(gòu)》(2021 年)和《持續(xù)架構(gòu):敏捷和以云為中心的世界中的可持續(xù)架構(gòu)》(2015 年)兩本書的合著者椎扬,并發(fā)表了許多關(guān)于這個主題的文章,還在多個軟件架構(gòu)會議上發(fā)表演講具温。
Kurt Bittner 擁有 30 多年的經(jīng)驗蚕涤,能夠在短時間內(nèi)以反饋為導(dǎo)向的周期交付可用的軟件。他幫助各種各樣的組織采用敏捷軟件交付實踐铣猩,包括大型銀行揖铜、保險、制造和零售組織以及大型政府機構(gòu)达皿。他曾就職于或服務(wù)于 Oracle天吓、HP、IBM 和 Microsoft 等大型軟件交付組織峦椰。他還是 Forrester Research 的前技術(shù)行業(yè)分析師龄寞,并撰寫了大量與敏捷團隊和領(lǐng)導(dǎo)力相關(guān)的主題文章。
原文鏈接:Software Architecture and the Art of Experimentation(https://www.infoq.com/articles/architecture-experimentation/)