敏捷架構應用

jopen 9年前發布 | 68K 次閱讀 敏捷 敏捷開發

原文  http://www.infoq.com/cn/articles/agile-architecture-applied


敏捷有適應性。什么時候以及如何應用架構取決于環境。本文首先解釋了為什么是這樣,然后說明了在敏捷環境中怎么樣才能仍然給予架構足夠的重視。適應性和對話是基本要素。

敏捷宣言十年前就已經問世,它的出現是對當時作為標準的計劃驅動方法的一種響應。在計劃驅動方法中,計劃工作和開展工作是單獨的步驟。編寫好的計 劃需要一個穩定的基礎:明確的需求。因此,確保需求穩定是一個明確的要求。基于那些穩定的需求,可以創建一個同樣穩定的架構,并隨后實現。

事實上,這是相當困難的,因為人類天生就不是那樣的。你們是否曾經參與過一個這樣的項目,它開始的時候有一個定義良好的、完整的需求說明書,你們 帶著它回到團隊,可能在國外,并制定了一個剛好十八個月的計劃,然后無需進一步的工作就可以開始滿足客戶需求?我們沒有。客戶會逐漸發現他們想要什么,開 發團隊會發現如何創建它,而與此同時,環境往往也在變化。

因此,敏捷有一種不同的計劃方法,它擁抱所有會為客戶增加價值的變化。該方法沒有提供構建“大設計(big design)”的基礎,也讓我們沒有意愿構建這樣一個設計,因為那樣的設計很脆弱。這不是說架構不再重要,不過,它必須健壯,能夠適應未來的變化。那究 竟上意味著什么?得看情況。還要提前做多少工作?夠用就好。

敏捷架構應用

你是不是已經知道這些答案?在敏捷宣言宣告敏捷十年后的今天,你是不是希望我們現在可以更具體一點?是的,我們也是如此!而且現在就挺好,因為我 們的客戶——我們組織內的業務方——期望值越來越高。成功不再是根據計劃交付,而是要交付能夠影響實際業務的軟件。像“影響地圖(Impact Mapping)”、“功能注入(Feature Injection)”、“用戶故事映射(User Story Mapping)”等技術迅速普及;它們中的每一個方法都能幫助我們構建適當的產品。而為了構建適當的產品,具有有效架構的方法不能停止不前。由于架構是 一個涉及面很廣的話題,所以為了講得更清楚,我們將接下來要重點探討的架構定義為軟件架構:單個應用程序的架構。

架構?我們采用測試驅動開發,并編寫整潔的代碼。

采用測試驅動開發對代碼設計非常有益。我們發現,它在我們由外向內工作時尤其有用,就像 TDD倫敦學校 所倡導的那樣從驗收測試向內。由外向內工作減少了增加各種if判斷代碼的趨勢。而且,你測試類的交互方式,測試并不是在以最嚴格的方式應用單元測試時創建的。根據我們的經驗,這些就是那些實際上可以為重構提供支持的測試,而不是障礙。

現在,如果你也編寫漂亮整潔、可以與讀者清晰溝通的代碼,那么幾乎可以肯定,你在細節上有一些非常好的東西。但整體上怎么樣呢?你如何用文檔記錄通過代碼不容易看出來的總體設計的方方面面?你如何討論它們,并達成一致?有一些容易理解的“ 架構草圖 ”是不是有好處呢?

敏捷架構應用

你可能不止一次繪制過草圖,不同于我們在項目中所繪制的。那我們可以問一下,誰在場嗎?架構師,領導,管理人員,還是你的整個團隊?后續在哪里重新審視和修改這些草圖?如果是這樣,那對項目有價值嗎?如果不是,什么妨礙了你?

在我看來,作為一個團隊,創建并維護這樣的資料是架構的基本組成部分。通過草繪架構并與所有參與編碼的人進行討論,可以將應用程序層面的關注點與 繁瑣的細節聯系起來。TDD提供了一種做詳細設計決策的框架,但是架構活動才能幫助你創建健壯的軟件。雖然幾乎任何東西在白板上看起來都不錯,但缺陷還是 會在代碼中形成,告訴你架構模型還不夠完善,或者不再完善了。

“層創(Emergence)”

有一個常見的誤解,就是敏捷不需要特別關注架構;于是,它先期就同定義架構的文檔一起被扔掉了。“ 敏捷宣言原則 ”中提到的層創概念被解釋為自然出現。一個更好的解釋是:我們一起逐步地做那件事。架構是一種團隊活動和共同的理解,而不是一個從象牙塔中傳遞給團隊的文檔。

最好的架構、需求和設計源于自組織團隊。

——敏捷宣言原則#11

層創屬性(emergent property) ”的特點是,它不能脫離派生它的系統部分而存在。我們無法由它追溯到一個特定的部分,但它影響著系統的每一部分。例如,當你去除了分子,水就沒有了流動 性。單個分子是不流動的,但水作為一個整體是流動的。類似地,沒有應用程序和團隊,也就沒有(層創)架構。你無法指出一個決定架構是什么的架構師。但共享 的概念框架影響著團隊的行為以及應用程序的樣子。傳統的流程中沒有這種說法。在這里,我們再一次看到,敏捷真地帶來了觀念的改變,專注于人與交互。

那么還有專職的架構師嗎?也許有,雖然與以前的角色不同。當與多個團隊一起開發一個應用(或者是姊妹應用)時,有其他人關注全局問題有助于團隊集中精力。 這樣,架構師就將架構作為一個基本關注點,但他致力于服務團隊,而不是向團隊發號施令,或者比團隊超前工作。他知道,如果他使團隊等待一個完美計劃的話, 他就沒有價值了,而且他們可以通過實現架構來幫助他證明架構的合理性。他會實驗和驗證,通過“ 峰值(spikes) ”以及定期與團隊成員一起編碼。在架構會議上,他會不斷地問團隊,他們討論的內容是否會與他們將來實際編寫的代碼一致。

可選項有價值

對變化有較好健壯性的架構是,在任何需要的時候都確實很容易變化的架構。這樣的架構不會沒必要地限制你的可選項。每當你做架構決策的時候,尤其是以后變化 會很難的決策,你就限制了你處理變化的能力。只有在知道為什么做那樣的決策的那個特定時刻,你才能作難以變化的決策,并且要本著負責任的態度不斷的尋找機 會延期決策。這就像在你的個人生活中:你會立即買一張音樂會的票,因為你估計很快就會賣光。但晚上與幾個朋友在酒吧里聚會可能是最后一分鐘才做出的安排。 此外,這意味著:循序漸進。不要讓應用程序處理(尚且)不必要的事情,但要確保后續容易添加。換句話說,通過使架構具有可擴展性,減少變化需求。將“ 開放—封閉原則 ”應用到架構。在接下來的兩節中,我們將更具體的進行描述。

簡單——使未完成的工作最大化的藝術——是根本。

敏捷宣言原則#10

簡單

循序漸進還意味著追求簡單,簡化到再進一步簡化就會去掉重要的價值。這是說積極刪除幾乎沒有價值的功能。它同樣也關乎應用本身的結構。從清晰的架 構圖到整潔的代碼實現,在任何層面上都是越簡單越容易理解。要把大量注意力放在組件布局上,并簡化組件本身。簡單的軟件是有適應性的軟件!

如何將應用劃分成組件?正當你打開開發環境的時候,應用程序告訴了你什么?我希望是它所提供的功能,而技術和框架不是它十分關注的。Alistair Cockburn 幾年前就建議 ,以同心圓方式分解比層疊方式更自然。使用這種分解方式的 架構模型 最近引起了人們的注意,并達到了有望成為新標準的程度。

敏捷架構應用

如果愿意,這樣一種設計的內核可以始于應用程序提供的功能、應用程序特性或者用例,如購買旅行卡、更換旅行卡、取消旅行卡。遺憾的是,雖然這些特 性是客戶所需要、應用程序所需提供的,但在許多應用程序中,要找出它們非常困難。我們希望將它們與它們所操縱的業務域實體區分開來。這樣,我們就圍繞業務 域把它們創建成一個單獨的層。你會發現,內核周圍有連接外部世界的接口。不只是連接用戶界面,還包括連接數據庫以及與其它系統互連的接口。你立馬就會發 現,最有可能變化的東西容易調整了:新增一個數據庫、一個移動用戶界面、提供一個服務接口等等。

無一例外,所有的依賴都是指向中央的。借助 依賴注入 ,每一層都完全獨立于其它層。外圈中的各種接口組件也不知道彼此的存在。

“有界上下文(Bounded contexts)”

我們就像上面這段時間剛剛討論過的那樣設計架構。我們已經體驗到了許多好處,不過有時候還是不滿意。隨著應用程序的擴展和時間的推移,內核的體量 往往會開始成為我們的沉重負擔。該模型基于這樣一種假設,由于實體代表了業務規則——最好是企業范圍內有效——所以它們很少會變化。正是這種穩定性使它可 以作為其它所有一切的基礎。但僅僅是逐步實現業務規則,隨著我們迭代增加特性,我們已經破壞了那種穩定性。企業的各個部門以及他們的系統通常也沒有統一穩 定的業務實體定義;它們取決于環境,也會隨著時間發展變化。

在某些時候,我們應該放棄一個統一內核的概念,轉而采用來自領域驅動設計的概念“ 有界上下文 ”。一個將兩個有界上下文分成兩個獨立模型的著名例子是“命令查詢職責分離(Command Query Responsibility Segregation,縮寫為 CQRS )。應用程序可以用多個類似的獨立模型服務于不同的業務上下文。這些上下文是為了允許模型針對不同的——通常是組織方面的——原因以不同的速度變化。方便起見,我們必須打破它們之間的“二進制依賴(binary dependencies)”。

敏捷架構應用

Russ Miles建議我們那樣做并轉而采用簡單事件進行組件間通信。一個人能夠獲得的自由非常有用,但它也是權衡的開始。例如,你是只想輕度解耦,還是準備好完全放棄利用交換強類型對象的優點,從而換取可提供的靈活性?

假如與主機的接口每年更新兩次,而且日期完全無法預測。同時,企業幾乎每個周都想更改他們提供的保險產品的業務規則,以便與市場機遇保持一致。你 大概會希望在不同的組件中處理這兩個問題,它們之間不存在任何方向上的二進制依賴。但是,這兩個組件是否可以同時依賴于介于它們之間的一個強類型接口,或 者只是通過一個沒有明確模式的、非常松散的數據結構進行交互,以便提供你所需要的靈活性?你可以擁有靈活性,但那會使兩個組件都更復雜,而且為了確保只將 兼容的組件投入生產環境,你需要進行更多的處理。

你發現自己在平衡靈活性和復雜性,而這種平衡很可能會隨著時間變化。這使得將功能明智地分組成組件很重要,而且每當新需求出現時,要重新審視分組,保持對架構的持續關注。因此,在Russ看來,這既是一個模型,也是一個 過程工具 。他將其稱為救生圈。

邊做邊學

當運用了我們討論的技術,你的應用程序會是什么樣子呢?我們不熟悉你的項目,也不相信象牙塔架構,所以我們不打算告訴你。它或許會反映你所面對的組織和約束。 Conway定律 有類似的描述,或許,那其實是件好事。

設計系統的組織……受到限制,產生的設計是對這些組織的溝通結構的復制

——M. Conway

因此,這就是我們送你上路的地方。從已知的規則入手:分割問題,尋求有限數量的、強內聚少依賴的組件。加上我們描述的敏捷原則:對變化持開放態度、團隊精神、協作、層創、簡單,最重要的是可用的軟件。

讓它成為你的思維方式,并且行動起來,不只是作為指定的架構師要如此,作為開發人員也要如此。沿著這條道路邊做邊學至關重要。問下自己,現在預先完成的工作有哪些部分團隊已經可以不做,什么狀況可以顯示團隊已經找到了更高效的滿足需求的方式。祝你好運!

關于作者

敏捷架構應用 Wim Heemskerk 為團隊實踐敏捷提供幫助。他是一名敏捷人士、軟件工匠和Stoosian。作為一名富有經驗的變革推動者,他增加流程、技術和組織工作的一致性。Wim將 互補模型及其原則串聯起來轉化為日常行動。他致力于創建可持續的變革,就是人們常說自己創建和想要的那種。他還為其他探索敏捷、領導力、優秀軟件和真正有 效的測試自動化的人提供支持。他的推ter賬號是 @WimHeemskerk

敏捷架構應用 Minze Tolsma 是一名軟件工匠,他對人們的工作和思考方式有濃厚興趣。他愿意接受一切可以增加客戶價值的方式。他堅信“身后一步(from one step behind)”的領導方式:保持靈活性,作為一名工匠,要設法完全了解所服務的企業,然后利用所有配備的工具行動起來。Minze為iPROFS(荷蘭 哈勒姆)工作,是一名軟件架構師和知識管理人員。你可以在 推terLinkedIn 上找到他。

查看英文原文:Agile Architecture Applied

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!