av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

深入分析軟件復(fù)雜度

軟件復(fù)雜度的成因

創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比汨羅網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式汨羅網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋汨羅地區(qū)。費用合理售后完善,十多年實體公司更值得信賴。

Eric Evans的經(jīng)典著作《領(lǐng)域驅(qū)動設(shè)計》的副標(biāo)題為“軟件核心復(fù)雜性應(yīng)對之道”,這說明了Eric對領(lǐng)域驅(qū)動設(shè)計的定位就是應(yīng)對軟件開發(fā)的復(fù)雜度。Eric甚至認(rèn)為:“領(lǐng)域驅(qū)動設(shè)計只有應(yīng)用在大型項目上才能產(chǎn)生***的收益”。他通過Smart UI反模式逆向地說明了在軟件設(shè)計與開發(fā)過程中如果出現(xiàn)了如下問題,就應(yīng)該考慮運用領(lǐng)域驅(qū)動設(shè)計:

  • 沒有對行為的重用,也沒有對業(yè)務(wù)問題的抽象。每當(dāng)操作用到業(yè)務(wù)規(guī)則時,都必須重復(fù)這些規(guī)則。
  • 快速的原型建立和迭代很快會達(dá)到其極限,因為抽象的缺乏限制了重構(gòu)的選擇。
  • 復(fù)雜的功能很快會讓你無所適從,所以程序的擴展只能是增加簡單的應(yīng)用模塊,沒有很好的辦法來實現(xiàn)更豐富的功能。

因此,選擇領(lǐng)域驅(qū)動設(shè)計,就是要與軟件系統(tǒng)的復(fù)雜作一番殊死拼搏,以降低軟件復(fù)雜度為己任。那么,什么才是復(fù)雜呢?

什么是復(fù)雜?

即使是研究復(fù)雜系統(tǒng)的專家,如《復(fù)雜》一書的作者Melanie Mitchell,都認(rèn)為復(fù)雜沒有一個明確得到公認(rèn)的定義。不過,Melanie Mitchell在接受Ubiquity雜志專訪時,還是“勉為其難”地給出了一個通俗的復(fù)雜系統(tǒng)定義:由大量相互作用的部分組成的系統(tǒng),與整個系統(tǒng)比起來,這些組成部分相對簡單,沒有中央控制,組成部分之間也沒有全局性的通訊,并且組成部分的相互作用導(dǎo)致了復(fù)雜行為。

這個定義庶幾可以表達(dá)軟件復(fù)雜度的特征。定義中的組成部分對于軟件系統(tǒng),就是我所謂的“設(shè)計單元”,基于粒度的不同可以是函數(shù)、對象、模塊、組件和服務(wù)。這些設(shè)計單元相對簡單,然而彼此之間的相互作用卻導(dǎo)致了軟件系統(tǒng)的復(fù)雜行為。

Jurgen Appelo從理解力與預(yù)測能力兩個維度分析了復(fù)雜系統(tǒng)理論,這兩個維度又各自分為不同的復(fù)雜層次,其中,理解力維度分為simple與comlicated兩個層次,預(yù)測能力維度則分為ordered,complex與chaotic三個層次,如下圖所示:

參考復(fù)雜的含義,complicated與simple(簡單)相對,意指非常難以理解,而complex則介于ordered(有序的)與chaotic(混沌的)之間,認(rèn)為在某種程度上可以預(yù)測,但會有很多出乎意料的事情發(fā)生。顯然,對于大多數(shù)軟件系統(tǒng)而言,系統(tǒng)的功能都是難以理解的;在對未來需求變化的把控上,雖然我們可以遵循一些設(shè)計原則來應(yīng)對可能的變化,但未來的不可預(yù)測性使得軟件系統(tǒng)的演進仍然存在不可預(yù)測的風(fēng)險。因此,軟件系統(tǒng)的所謂“復(fù)雜”其實覆蓋了complicated與complex兩個方面。要理解軟件復(fù)雜度的成因,就應(yīng)該結(jié)合理解力與預(yù)測能力這兩個因素來幫助我們思考。

理解力

在軟件系統(tǒng)中,是什么阻礙了開發(fā)人員對它的理解?想象團隊招入一位新人,就像一位游客來到了一座陌生的城市,他是否會迷失在阡陌交錯的城市交通體系中,不辨方向?倘若這座城市實則是鄉(xiāng)野郊外的一座村落,不過只有房屋數(shù)間,一條街道連通城市的兩頭,還會生出迷失之感嗎?

因而,影響理解力的***要素是規(guī)模。

1. 規(guī)模

軟件的需求決定了系統(tǒng)的規(guī)模。當(dāng)需求呈現(xiàn)線性增長的趨勢時,為了實現(xiàn)這些功能,軟件規(guī)模也會以近似的速度增長。由于需求不可能做到完全獨立,導(dǎo)致出現(xiàn)相互影響相互依賴的關(guān)系,修改一處就會牽一發(fā)而動全身。就好似城市的一條道路因為施工需要臨時關(guān)閉,此路不通,通行的車輛只得改道繞行,這又導(dǎo)致了其他原本已經(jīng)飽和的道路因為涌入更多車輛而超出道路的負(fù)載變得更加擁堵,這種擁堵現(xiàn)象又會順勢向這些道路的其他分叉道路蔓延,形成一種輻射效應(yīng)的擁堵現(xiàn)象。

軟件開發(fā)的擁堵現(xiàn)象或許更嚴(yán)重:

  • 函數(shù)存在副作用,調(diào)用時可能對函數(shù)的結(jié)果作了隱含的假設(shè);
  • 類的職責(zé)繁多,不敢輕易修改,因為不知這種變化會影響到哪些模塊;
  • 熱點代碼被頻繁變更,職責(zé)被包裹了一層又一層,沒有清晰的邊界;
  • 在系統(tǒng)某個角落,隱藏著伺機而動的Bug,當(dāng)誘發(fā)條件具備時,就會讓整條調(diào)用鏈癱瘓;
  • 不同的業(yè)務(wù)場景包含了不同的例外場景,每種例外場景的處理方式都各不相同;
  • 同步處理與異步處理代碼糾纏在一起,不可預(yù)知程序執(zhí)行的順序。

當(dāng)需求增多時,軟件系統(tǒng)的規(guī)模也會增大,且這種增長趨勢并非線性增長,會更加陡峭。倘若需求還產(chǎn)生了事先未曾預(yù)料到的變化,我們又沒有足夠的風(fēng)險應(yīng)對措施,在時間緊迫的情況下,難免會對設(shè)計做出妥協(xié),頭疼醫(yī)頭,腳疼醫(yī)腳,在系統(tǒng)的各個地方打上補丁,從而欠下技術(shù)債(Technical Debt)。當(dāng)技術(shù)債務(wù)越欠越多,累計到某個臨界點時,就會量變引起質(zhì)變,整個軟件系統(tǒng)的復(fù)雜度達(dá)到***,步入衰亡的老年期,成為“可怕”的遺留系統(tǒng)。正如飼養(yǎng)場的“奶牛規(guī)則”:奶牛逐漸衰老,最終無奶可擠;然而與此同時,飼養(yǎng)成本卻在上升。

2. 結(jié)構(gòu)

你去過迷宮嗎?相似而回旋繁復(fù)的結(jié)構(gòu)使得本來封閉狹小的空間被魔法般地擴展為一個***的空間,變得無窮大,仿佛這空間被安置了一個循環(huán),倘若沒有找到正確的退出條件,循環(huán)就會無休無止,永遠(yuǎn)無法退出。許多規(guī)模較小卻格外復(fù)雜的軟件系統(tǒng),就好似這樣的一座迷宮。

此時,結(jié)構(gòu)成了決定系統(tǒng)復(fù)雜度的關(guān)鍵因素。

結(jié)構(gòu)之所以變得復(fù)雜,多數(shù)情況下還是因為系統(tǒng)的質(zhì)量屬性決定的。例如,我們需要滿足高性能、高并發(fā)的需求,就需要考慮在系統(tǒng)中引入緩存、并行處理、CDN、異步消息以及支持分區(qū)的可伸縮結(jié)構(gòu)。倘若我們需要支持對海量數(shù)據(jù)的高效分析,就得考慮這些海量數(shù)據(jù)該如何分布存儲,并如何有效地利用各個節(jié)點的內(nèi)存與CPU資源執(zhí)行運算。

從系統(tǒng)結(jié)構(gòu)的視角看,單體架構(gòu)一定比微服務(wù)架構(gòu)更簡單,更便于掌控,正如單細(xì)胞生物比人體的生理結(jié)構(gòu)要簡單數(shù)百倍;那么,為何還有這么多軟件組織開始清算自己的軟件資產(chǎn),花費大量人力物力對現(xiàn)有的單體架構(gòu)進行重構(gòu),走向微服務(wù)化?究其主因,不還是系統(tǒng)的質(zhì)量屬性在作祟嗎?

縱觀軟件設(shè)計的歷史,不是分久必合,合久必分,而是不斷拆分繼續(xù)拆分持續(xù)拆分的微型化過程。分解的軟件元素不可能單兵作戰(zhàn)。怎么協(xié)同,怎么通信,就成為了系統(tǒng)分解后面臨的主要問題。如果沒有控制好,這些問題固有的復(fù)雜度甚至?xí)谀承﹫鼍跋鲁^因為分解給我們帶來的收益。

無論是優(yōu)雅的設(shè)計,還是拙劣的設(shè)計,都可能因為某種設(shè)計權(quán)衡而導(dǎo)致系統(tǒng)結(jié)構(gòu)變得復(fù)雜。唯一的區(qū)別在于前者是主動地控制結(jié)構(gòu)的復(fù)雜度,而后者帶來的復(fù)雜度是偶發(fā)的,是錯誤的滋生,是一種技術(shù)債,它可能會隨著系統(tǒng)規(guī)模的增大而導(dǎo)致一種無序設(shè)計。

在Pete Goodliffe講述的《兩個系統(tǒng)的故事:現(xiàn)代軟件神話》中詳細(xì)地羅列了無序設(shè)計系統(tǒng)的幾種警告信號:

  • 代碼沒有顯而易見的進入系統(tǒng)中的路徑;
  • 不存在一致性、不存在風(fēng)格、也沒有統(tǒng)一的概念能夠?qū)⒉煌牟糠纸M織在一起
  • 系統(tǒng)中的控制流讓人覺得不舒服,無法預(yù)測
  • 系統(tǒng)中有太多的“壞味道”,整個代碼庫散發(fā)著腐爛的氣味,是在大熱天里散發(fā)著刺激氣體的一個垃圾堆
  • 數(shù)據(jù)很少放在使用它的地方。經(jīng)常引入額外的巴羅克式緩存層,目的是試圖讓數(shù)據(jù)停留在更方便的地方。

我們看一個無序設(shè)計的軟件系統(tǒng),就好像隔著一層半透明的玻璃觀察事物一般,系統(tǒng)中的軟件元素都變得模糊不清,充斥著各種技術(shù)債。細(xì)節(jié)層面,代碼污濁不堪,違背了“高內(nèi)聚松耦合”的設(shè)計原則,導(dǎo)致許多代碼要么放錯了位置,要么出現(xiàn)重復(fù)的代碼塊;架構(gòu)層面,缺乏清晰的邊界,各種通信與調(diào)用依賴糾纏在一起,同一問題域的解決方案各式各樣,讓人眼花繚亂,仿佛進入了沒有規(guī)則的無序社會。

預(yù)測能力

當(dāng)我們掌握了事物發(fā)展的客觀規(guī)律時,我們就具有了一定的對未來的預(yù)測能力。例如我們洞察了萬有引力的本質(zhì),就可以對我們能夠觀察到的宇宙天體建立模型,相對準(zhǔn)確地推測出各個天體在未來一段時間的運行軌跡。然而,宇宙空間變化莫測,或許因為一個星球的死亡產(chǎn)生黑洞的吸噬能力,就可能導(dǎo)致那一片星域產(chǎn)生劇烈的動蕩,這種動蕩會傳遞到更遠(yuǎn)的星空,從而干擾了我們的預(yù)測。坦白說,我們現(xiàn)在連自己居住的地球天氣都不能做一個準(zhǔn)確的預(yù)測,何敢妄談對星空的預(yù)測?之所以如此,正是因為未知的變化的產(chǎn)生。

1. 變化

未來總會出現(xiàn)不可預(yù)測的變化。這種不可預(yù)測性帶來的復(fù)雜度,使得我們產(chǎn)生畏懼,因為我們不知道何時會發(fā)生變化,變化的方向又會走向哪里,這就導(dǎo)致心理滋生一種仿若失重一般的感覺。變化讓事物失去控制,受到事物牽扯的我們會感到惶恐不安。

在設(shè)計軟件系統(tǒng)時,變化讓我們患得患失,不知道如何把握系統(tǒng)設(shè)計的度。若拒絕對變化做出理智的預(yù)測,系統(tǒng)的設(shè)計會變得僵化,一旦變化發(fā)生,修改的成本會非常的大;若過于看重變化產(chǎn)生的影響,渴望涵蓋一切變化的可能,一旦預(yù)期的變化不曾發(fā)生,我們之前為變化付出的成本就再也補償不回來了。這就是所謂的“過度設(shè)計”。

從需求的角度講,變化可能來自業(yè)務(wù)需求,也可能來自質(zhì)量屬性。以對系統(tǒng)架構(gòu)的影響而言,尤以后者為甚,因為它可能牽涉到整個基礎(chǔ)架構(gòu)的變更。George Fairbanks在《恰如其分的軟件架構(gòu)》一書中介紹了郵件托管服務(wù)公司RackSpace的日志架構(gòu)變遷,業(yè)務(wù)功能沒有任何變化,卻因為郵件數(shù)量的持續(xù)增長,為滿足性能需求,架構(gòu)經(jīng)歷了三個完全不同解決方案的變遷:從最初的本地日志文件,到中央數(shù)據(jù)庫,再到基于HDFS的分布式存儲,整個系統(tǒng)幾乎發(fā)生了顛覆性的變化。這并非RackSpace的設(shè)計師欠缺設(shè)計能力,而是在公司草創(chuàng)之初,他們沒有能夠高瞻遠(yuǎn)矚地預(yù)見到客戶數(shù)量的增長,導(dǎo)致日志數(shù)據(jù)增多,以至于超出了已有系統(tǒng)支持的能力范圍。俗話說:“事后諸葛亮”,當(dāng)我們在對一個軟件系統(tǒng)的架構(gòu)設(shè)計進行復(fù)盤時,總會發(fā)現(xiàn)許多設(shè)計決策是如此的愚昧。殊不知這并非愚昧,而是在設(shè)計當(dāng)初,我們手中掌握的籌碼不足以讓自己贏下這場面對未來的戰(zhàn)爭罷了。

2. 這就是變化之殤!

如果將軟件系統(tǒng)中我們自己開發(fā)的部分都劃歸為需求的范疇,那么還有一種變化,則是因為我們依賴的第三方庫、框架或平臺、甚至語言版本的變化帶來的連鎖反應(yīng)。例如,作為Java開發(fā)人員,一定更垂涎于Lambda表達(dá)式的簡潔與抽象,又或者Jigsaw提供的模塊定義能力,然而現(xiàn)實是我們看到多數(shù)的企業(yè)軟件系統(tǒng)依舊在Java 6或者Java 7中裹足不前。

這還算是幸運的例子,因為我們盡可以滿足這種故步自封,因為情況并沒有到必須變化的境地。但當(dāng)我們依賴的第三方有讓我們不得不改變的理由時,難道我們還能拒絕變化嗎?

許多軟件在版本變遷過程中都盡量考慮到API變化對調(diào)用者帶來的影響,因而盡可能保持版本向后兼容。我親自參與過系統(tǒng)從Spring 2.0到4.0的升級,Spark從1.3.1到1.5再到1.6的升級,感謝這些框架或平臺設(shè)計人員對兼容性的體貼照顧,使得我們的升級成本能夠被降到***;但是在升級之后,倘若沒有對系統(tǒng)做全方位的回歸測試,我們的內(nèi)心始終是惴惴不安的。

對第三方的依賴看似簡單,殊不知我們所依賴的庫、平臺或者框架又可能依賴了若干對于它們而言又份屬第三方的更多庫、平臺和框架。每回初次構(gòu)建軟件系統(tǒng)時,我都為漫長等待的依賴下載過程而感覺煩躁不安。多種版本共存時可能帶來的所謂依賴地獄,只要親身經(jīng)歷過,就沒有不感到不寒而栗的。倘若你運氣欠佳,可能還會有各種古怪問題接踵而來,讓你應(yīng)接不暇,疲于奔命。

如果變化是不可預(yù)測的,那么軟件系統(tǒng)也會變得不可預(yù)測。一方面我們要盡可能地控制變化,至少要將變化產(chǎn)生的影響限制在較小的空間范圍內(nèi);另一方面又要保證系統(tǒng)不會因為滿足可擴展性而變得更加復(fù)雜,***背上過度設(shè)計的壞名聲。軟件設(shè)計者們就像走在高空鋼纜的技巧挑戰(zhàn)者,驚險地調(diào)整重心以維持行動的平衡。故而,變化之難,在于如何平衡。

【本文為專欄作者“張逸”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】


當(dāng)前題目:深入分析軟件復(fù)雜度
標(biāo)題鏈接:http://uogjgqi.cn/article/cdhegsg.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流