軟件的複雜性與構造定律

快看!看!深入研究自然,你就會明白一切。 - 愛因斯坦

複雜性是被低估的。複雜越高,開發人員會感到不安。對其的理解認知負荷代價就越高,我們就更不快樂。真正的挑戰是在構建我們的系統時要保持其有序以及工程師的生產方式。對於這一點,一個簡單的物理規律可以幫助我們:構造定律 the Constructal Law.

當我們擁有臃腫大量的組件和類時,其中每一個又由大量的職責行爲功能組成,我們不會在系統層面去思考,相反,我們只是將大量脂肪性質類進行組羣,從外表看,你是無法找出這個系統做什麼用的,這個系統代表的,業務需求或用戶案例是什麼。因爲我們的應用程序進行了隱藏。

Neil Johnson, 在其a big proponent of Complexity Science中對複雜系統的定義如下:

(複雜的)系統表現出是一種複雜的有序和無序行爲的混合。

對於軟件來說,這種複雜的系統一般不是偶然發生的,它它是人類人爲的結果。是工程師在以有序和可持續的方式構建組件和系統。    

最聰明的人自從60年代開始在計算機科學已經進行了不少最佳實踐。然而,這是不夠的。雖然我們已經從自然中得到啓發解決了我們的不少困難問題,如神經網絡、能源發電和液壓。令人驚訝的是,當談到複雜性,自然也有一種複雜的方法來解決這一問題:在有序和無序中平衡。

 

有序和無序

軟件設計者應該是分離應該分離事物,而不是將本應一起考慮的事情進行分離。-Kent Beck

當我們決定打破臃腫的組件分離成小和孤立的部分時,我們面臨着一個巨大的編程悖論:起初,一切都是彩虹和獨角獸。但是後來,缺非如此。也就是說,事情並沒有我們起初想得那麼簡單。

最初,我們第一次努力隔離後,我們會很高興。一切看起來是有些緊張的和美麗的。然而,很快事情開始分崩離析,我們最終得到的東西比我們最初的組件要差得多。組件和類變得很大複雜瞭如下圖:

那麼下面最自然的事情是什麼?放棄,回到我們當初的,繼續臃腫的類。這樣我們會感覺更好,但實際上我們是在倒退。這些組件不是問題。問題是複雜性,它是一個活着的野獸,會盡一切可能增長,你需要學會馴服它。(Quoting Neil Johnson)

(複雜的)系統似乎是"活着"。系統是在一個高度不平凡的且經常複雜的方式演進發展,這是由一個代理的生態驅動着,這些代理相互作用交互,且在對不斷的反饋下不斷地適應。

複雜性會增加

讓我們將系統的複雜性看成是兩個組件之間的許多交互,在兩個組件情況下,複雜度是1,如下圖:

如果增加一個組件,複雜度將從1增加到3:

複雜度以指數級的增長是驚人的,當我們增加到六個組件,複雜度將是15。

顯然,這種拓撲可能是一個極端,但卻能公平地明複雜性需要馴服。老實說,這個極端的例子並不少見,這正是人們做的事情,複雜性感染一切。什麼出錯了嗎?

構造定律Constructal Law

自然界是如何應對這複雜呢?這在物理中被稱爲構造定律 Constructal Law, 僅有的我們知曉的大自然是如何指導複雜演化的規律(可以說是上帝創造萬物的方式),是由Adrian Bejan於1995創立的構造定律:

For a finite-size system to persist in time (to live), it must evolve in such a way that it provides easier access to the imposed currents that flow through it.

對於一個有限大小的持續活動的系統,它必須以這種方式發展演進:它提供了一種在自身元素之間更容易訪問的流動方式。

這個定理在自然中比比皆是,典型的是樹的生長,先有根,再有枝,枝上再生枝葉。這種自發性質的設計反映了這一趨勢:他們允許實體或事物更容易地流動 - 以最少的能量消耗到達最遠的地方,就連街道和道路這些人爲地構建物體,往往也是有排序的模式,以提供最大的靈活性。

構造定律致力於描述能量和物質在物理網絡(如河流)和生物網絡(如血管)中的流動,這個理論提出,如果一個流體系統(flow system)要繼續存在(比如,生存),那麼他必須始終提供更容易的方式來獲得這個系統中的流體。換句話說,系統應該致力於將能量消耗減少到最低限度,而同時將消耗單位能量產生的熵提高到最大限度

Bejan相信,進化實質上是這麼一個過程,即生物體不斷的重組他們自身,以使能量和物質能夠儘可能迅速高效的通過他們。更好的流體結構(flow structure),不管它們是動物還是河流,將取代那些較差的結構。。

構造定律作爲第二個時間箭頭,將和熱力學第二定律一道將宇宙推向無序。

 

用構造定律進行有序化

回到我們這個複雜系統案例,我們可以使用構造定律降低複雜度,增加第7個組件後,將系統複雜度從15降低到8。

爲了實現這種方式開發,你需要了解你的對象不是隔離的實體,而是一個大概念的一部分,比如這個大概念是你的webservice 客戶端, 由很多對象組成包括連接 授權和XML文本 響應等。另外一個概念是你的數據庫組件,它是由許多對象組成,如ORM Active Record類,校驗類 連接類或它們之間的關係,這個大概念是一個聚合羣組,聚合了很多子對象於其中,是一個集合概念。

下面以一種模塊化分離關注是更加有意義:

 

與構造定律共存

在開發,不要讓你的直覺欺騙你以至於產生馬虎的代碼。不要讓一個模塊的一部分調用另一個模塊的內部組成部分。如下圖:

 

對於一個組件A和X個組件之間的交互,每一次A的改變將需要1+ x 改變。

組件之間的交互越少,越好,遠離扁平,用模塊進行封裝,我們能確保我們的系統增加時不會被複雜性淹沒。

 

英文原文:Complexity in Software 3: The Constructal Law

加法是自然之道

ORM和Rails的問題

發佈了200 篇原創文章 · 獲贊 27 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章