|
原文鏈接:The Pragmatic Architect - To Boldly Go Where No One Has Gone Before
本文首次發(fā)表在 IEEE Software ,并由 InfoQ 和 IEEE 計(jì)算機(jī)協(xié)會為您引進(jìn)。
是什么讓架構(gòu)師們精通自己的技藝?熟練的架構(gòu)師是如何進(jìn)行設(shè)計(jì)的?一次次,有人問起我這些問題,而我也不止一遍的問我自己。很明顯,這并不只是軟件工程過程、設(shè)計(jì)方法、技術(shù)或是編程的專業(yè)程度所決定的。很多架構(gòu)師具備令人欽佩且完備的技術(shù)知識,這確實(shí)是使設(shè)計(jì)成功的必要條件。但是,還是有很多的軟件項(xiàng)目失敗了,或是在項(xiàng)目的架構(gòu)中遭受到了嚴(yán)峻的挑戰(zhàn)。掌握此道的關(guān)鍵在于架構(gòu)師是以什么方式實(shí)現(xiàn)設(shè)計(jì),他們重視什么,他們關(guān)注哪些方面以及在這些方面努力著。
(缺失的)線條能告訴我們什么
圖1展示了摘自以前項(xiàng)目的一張高層次圖表,那個(gè)項(xiàng)目的架構(gòu)師創(chuàng)建了該圖以闡述系統(tǒng)的基本設(shè)計(jì)。
該圖大致描述了系統(tǒng)的關(guān)鍵組件、各組件的職責(zé)以及它們核心的模塊化原理。架構(gòu)師使用這些概要圖來交流設(shè)計(jì),以管理開發(fā)的過程,并以此討論它們在業(yè)務(wù)方面產(chǎn)生的影響,例如:成本、時(shí)間和精力等。然而,一段時(shí)間后,管理層會想要知道項(xiàng)目為什么會有重大延期以及預(yù)算為什么會超支,他們無法從架構(gòu)師的報(bào)告中獲得任何提示或指標(biāo)。
問題來自于該圖上的點(diǎn)狀黑線以及那些“尚未顯示的線條”。這些點(diǎn)狀黑線表示了該項(xiàng)目開發(fā)的一個(gè)專有的消息中間件。在圖上無法找到所羅列的這些組件之間的通信關(guān)系,特別要強(qiáng)調(diào)的是,這些關(guān)系是通過這個(gè)中間件運(yùn)作的。該項(xiàng)目的架構(gòu)師并不認(rèn)為值得對這些方面值建模或報(bào)告,因?yàn)閺乃麄兊囊暯莵砜矗鼈兇淼氖腔炯夹g(shù)的基礎(chǔ)設(shè)施,并不會有助于系統(tǒng)的領(lǐng)域和業(yè)務(wù)用例。然而,中間件的開發(fā)消耗了大量預(yù)算,因?yàn)檫@個(gè)過程中涉及到很多健壯性和性能的問題,我們不得不從系統(tǒng)的其他部分中抽調(diào)最好的開發(fā)人員來解決這些缺陷。另外,支撐這些中間件問題也需要在領(lǐng)域組件中付出相當(dāng)多的努力。
圖1.一幅用于和業(yè)務(wù)利益相關(guān)者交流關(guān)鍵設(shè)計(jì)的高層次架構(gòu)概要圖
事物間的設(shè)計(jì)
過往的經(jīng)驗(yàn)顯示,系統(tǒng)的架構(gòu)師們常常將注意力過多地集中于一些“明顯”的事物上:用戶接口、領(lǐng)域特定組件、數(shù)據(jù)管理以及持久化等。然而架構(gòu)的問題并不在組件之內(nèi),而是在組件之間:與其他系統(tǒng)之間的接口,交互以及集成——包括底層的技術(shù)基礎(chǔ)設(shè)施。但是架構(gòu)規(guī)范里幾乎不涉及這些方面,所以在這些方面發(fā)生問題之前,架構(gòu)師和開發(fā)人員都不會給予關(guān)注。
與此相反,注重實(shí)效的架構(gòu)師們更關(guān)注事物之間的事物——就是說,組件之間的事物以及代碼行(LOC)之間的事物,例如標(biāo)準(zhǔn)數(shù)據(jù)類型背后的領(lǐng)域思想。當(dāng)然,他們也會指導(dǎo)系統(tǒng)實(shí)際組件的設(shè)計(jì),但是當(dāng)指導(dǎo)通常足夠充分以支持更進(jìn)一步拆分并且可由開發(fā)團(tuán)隊(duì)實(shí)現(xiàn)時(shí),這些事物之間的事物實(shí)際上需要架構(gòu)師們親手處理。而且必須是他們,這是他們的領(lǐng)域——特別是在我們還不確定如何實(shí)際地設(shè)計(jì)這些“事物”時(shí)。下面讓我們?nèi)ヌ骄恳幌伦⒅貙?shí)效的架構(gòu)師們的秘密。
發(fā)現(xiàn)隱藏的領(lǐng)域概念
最近我在我們的幾個(gè)系統(tǒng)的代碼上運(yùn)行tag-cloud生成器。我想通過這種方式對這些系統(tǒng)中重要的領(lǐng)域概念有個(gè)大致的印象。出人意料的是,在這些系統(tǒng)中最頂端的數(shù)據(jù)類型是 string 和 int。然而我懷疑是不是真的如此,因?yàn)樵卺槍I(yè)工程或能源管理的系統(tǒng)中,其他概念會更加重要:設(shè)備、電力線、傳感器、制動器、標(biāo)簽、警報(bào)等等。當(dāng)我更深入地查看代碼時(shí),就發(fā)現(xiàn)了這些領(lǐng)域概念——但是它們分散在表面上幾乎不怎么相關(guān)的諸如 string 和 int 這樣基本類型的配置中。
如此隱藏的領(lǐng)域概念可能需要開發(fā)者們花費(fèi)相當(dāng)多的努力來理解和實(shí)現(xiàn)系統(tǒng),以保證產(chǎn)品的質(zhì)量。我如何才能知道一個(gè) int 實(shí)際表示的是某個(gè)特定的領(lǐng)域概念?我如何保證在某個(gè)特定的計(jì)算上下文中使用 int 時(shí)會執(zhí)行特定領(lǐng)域概念的契約?我不能,除非通過注釋和約定,其他的都對實(shí)踐沒有實(shí)質(zhì)幫助。圖2展示了摘自導(dǎo)致 Ariane 5 在其 1996 年首飛時(shí)墜毀的(標(biāo)有注釋的)代碼片段,其根本原因是源于對整型數(shù)溢出的保護(hù)不足。
圖2. 摘自 Ariane 5 的代碼片段。因?yàn)閷φ蛿?shù)溢出的保護(hù)不足導(dǎo)致了 Ariane 5 在其 1996 年首飛時(shí)墜毀。
我們有足夠的勇氣說,如果開發(fā)者以定義好的方式使用契約,將速度建模成一種合適的類型,那么 Ariane 5 的軟件錯(cuò)誤原本是可以避免的。然而這個(gè)例子也很好的把握了顯式建模的重要性。
即使領(lǐng)域概念很明顯、很清楚,但也可能埋藏在無數(shù)的細(xì)節(jié)之下。舉個(gè)例子,我曾經(jīng)研究過一個(gè)系統(tǒng)的復(fù)雜性。該軟件包含了一個(gè)命名服務(wù),該服務(wù)擁有一個(gè)包括 300 多種方法的接口。該服務(wù)的實(shí)際契約已經(jīng)幾乎看不清楚,而開發(fā)者們需要非常努力才能正確和有效地使用它。有分析表明,不超過 20 個(gè)方法就完全可以說明一個(gè)服務(wù)的必要契約。
注重實(shí)效的架構(gòu)師因此會非常重視并做好相關(guān)的工作,在他們的架構(gòu)中對所有領(lǐng)域概念進(jìn)行明確的描述,例如那些常被粗粒度描述的組件,細(xì)微的特定領(lǐng)域的數(shù)據(jù)類型,有意義的接口,等等。在對概念的建模中,注重實(shí)效的架構(gòu)師總是專注于精簡而避免混亂或復(fù)雜,并著重強(qiáng)調(diào)概念的本質(zhì)。這樣一來,系統(tǒng)中那些隱藏的概念或是相關(guān)的性能都會立即明朗起來,這將會幫助開發(fā)人員更好的識別它們,并把它們看作獨(dú)特的、明確的、有意義的類型(types)。用途(Usage)轉(zhuǎn)變成類型——對于創(chuàng)建有表現(xiàn)力的軟件設(shè)計(jì)和健壯的實(shí)現(xiàn)來說是一種重要的實(shí)踐。
在事物銜接之處
什么是架構(gòu)?Eoin Woods 對于該問題思考了相當(dāng)長一段時(shí)候后找到了一個(gè)答案。“那些很多被架構(gòu)師每天在使用著的思想:框架,代理,層次,接口,消息通知,連接器…這都是與間隙(gaps)相關(guān)的![...] 架構(gòu)是一種用于連接軟件設(shè)計(jì)師們一起工作的粘合劑,共同創(chuàng)造一個(gè)彈性的、靈活的、可擴(kuò)展的以及最終可用的系統(tǒng)。”
在這個(gè)結(jié)論中包含著很多道理。我確定所有人都知道關(guān)于組件接口不支持工作流,而我們系統(tǒng)不得不支持的事。在很多項(xiàng)目中,集成——無論是系統(tǒng)集成還是“僅僅”是系統(tǒng)構(gòu)成組件的集成——是成本最高的地方。而間隙(gaps)是指事物間銜接處的空間,組件交互的地方——沒有一方會對其負(fù)責(zé),除了注重實(shí)效的架構(gòu)師!所以設(shè)計(jì)簡潔及有意義的組件接口來支持組件間工作流的實(shí)現(xiàn)確實(shí)是不平凡的任務(wù)。在組件間定義符合用戶在系統(tǒng)上執(zhí)行任務(wù)那樣的交互是一件困難的事。甚至更難的是將一個(gè)系統(tǒng)與其他系統(tǒng)集成,使其在不喪失任一相關(guān)系統(tǒng)獨(dú)立質(zhì)量的情況下支持跨系統(tǒng)的工作流。你可以快速瀏覽一下支持該結(jié)論主題方面的模式著作。
“空隙(void)”事實(shí)上需要架構(gòu)師更多的關(guān)注和親身實(shí)踐。然而重點(diǎn)并非事物之間的適配——接口,交互,組件,系統(tǒng)——這些肯定是要連接的;重要的是隨著對工作流的支持之后這些事物之間的協(xié)調(diào)性。目標(biāo)是最精益(leanest)的適配,并且最深刻(impressive)的映射!這就是架構(gòu)產(chǎn)生的地方;此處的決策將對系統(tǒng)的生命周期成本產(chǎn)生非常大的影響。本段開篇提到的戰(zhàn)爭故事也就恰好定格在這里:事物在哪里銜接。
我們可以對獨(dú)立系統(tǒng)間那些“在中間(in-between)”的所有類型的工件的設(shè)計(jì)思想進(jìn)行擴(kuò)展——舉個(gè)例子,駐留于不同計(jì)算節(jié)點(diǎn)上,在不同的進(jìn)程中或是在不同的線程中各個(gè)部分。我曾看到過一些失敗的項(xiàng)目,之所以失敗是因?yàn)樵谒麄兊奶幚韺?shí)體(processing entities)之間粘合的時(shí)候采用了一種幼稚的方式。其實(shí)在跨越計(jì)算機(jī)、進(jìn)程和線程的分布式實(shí)體之間建立工作交互比較簡單。這就是對設(shè)計(jì)的掌控,無論如何,創(chuàng)建(分布式)進(jìn)程之間的交互可以最小化網(wǎng)絡(luò)交互和對線程間同步的需求。
以不確定作為驅(qū)動
我們都會抱怨那些模糊的系統(tǒng)需求。然而縱使業(yè)務(wù)的利益相關(guān)者們進(jìn)行了最仔細(xì)的需求捕獲工作,這都無法完全解決所有的歧義和不確定性:這就是事實(shí)。同樣,軟件工程師可能需要針對特定的需求費(fèi)心選擇各種可選解決方案,并在討論該采用哪種方案上花費(fèi)大量時(shí)間。但是架構(gòu)師則必須要面對來自設(shè)計(jì)、開發(fā)以及交付系統(tǒng)帶來挑戰(zhàn),并且在系統(tǒng)發(fā)布和后續(xù)的整個(gè)生命周期中都能保證滿足相關(guān)的業(yè)務(wù)需求。系統(tǒng)開發(fā)的時(shí)間越長,系統(tǒng)的生命周期越長,不確定性也就越大。
在這種形勢下,架構(gòu)師們會選擇一種最典型的規(guī)避方式,那就是泛型——它可以最大程度地帶來靈活性。架構(gòu)通過彈性機(jī)制來應(yīng)對過載,這在理論上支持所有可想象的系統(tǒng)配置,但是并不能滿足任何有意義配置的具體(非功能性)需求。
注重實(shí)效的架構(gòu)師能察覺到危險(xiǎn)地帶并以不確定性為驅(qū)動來做好決策。首先,他們承認(rèn)需要在各種可選項(xiàng)中做好選擇,并針對他們設(shè)計(jì)中的可變方面做出工作,以此來限制變化或選擇造成的影響。他們會深入探索系統(tǒng)的使用場景,以此來澄清需求中的不確定性或?qū)σ环N特殊設(shè)計(jì)選項(xiàng)的選擇,從而實(shí)現(xiàn)出場景的原型或可運(yùn)行骨架系統(tǒng)(walking skeleton)的一個(gè)部分。并且,他們非常歡迎來自于原型和可運(yùn)行骨架系統(tǒng)的循環(huán)反饋,以驅(qū)動或調(diào)整他們的決策。架構(gòu)師們重復(fù)地在事物之間(本例中是指在有歧義和不確定的需求或可選設(shè)計(jì)選項(xiàng)之間)進(jìn)行著設(shè)計(jì)。
本文的標(biāo)題是“大膽行前人未行之路”,架構(gòu)設(shè)計(jì)恰好就需要如此。來到事物之間:在代碼行上或其間,發(fā)現(xiàn)隱藏的領(lǐng)域概念;在你的系統(tǒng)和其他系統(tǒng)的組件之間,可以引導(dǎo)你設(shè)計(jì)好接口和工作流;在不確定性及可選項(xiàng)之間,驅(qū)動你的決策。架構(gòu)師的工作就是去盡早地發(fā)現(xiàn)這些“在中間的”事物,使它們更加明確,從中做出決策。以上這些加上扎實(shí)的有關(guān)架構(gòu)方法和技術(shù)的專業(yè)知識,以及謹(jǐn)慎的實(shí)踐,就是對架構(gòu)的精通之道:在軟件系統(tǒng)的痛點(diǎn)上進(jìn)行深思熟慮并最終決定它的成敗。
參考文獻(xiàn)
- J-J. Levy, (in French), 2010.
- J-L. Lions et al., 1996.
- E. Evans, Domain Driven Design, Addison- Wesley, 2004.
- F. Buschmann and K. Henney, "Five Considerations for Software Architecture, Part 1, IEEE Software, vol. 27, no. 3, 2010, pp. 63-65.
- E. Woods, 2011.
- F. Buschmann, "Unusable Software Is Useless, Part 1," IEEE Software, vol. 28, no. 1, 2011, pp. 92-94.
- F. Buschmann, K. Henney, and D.C. Schmidt, Pattern-Oriented Software Architecture-A Pattern Language for Distributed Computing, John Wiley and Sons, 2007.
- G. Hohpe and B. Woolf, Enterprise Integration Patterns-Designing, Building, and Deploying Messaging Solutions, Addison-Wesley, 2003.
- F. Buschmann, "Learning from Failure, Part 2: Featuritis, Performitis, and Other Diseases," IEEE Software, vol. 27, no. 1, 2010, pp. 10-11.
- K. Henney, "Use Uncertainty as a Driver," 97 Things Every Software Architect Should Know, R. Monson-Haefel, ed., O’Reilly, 2009, pp. 321-361.
it知識庫:注重實(shí)效的架構(gòu)師——大膽行前人未行之路,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。