董榮勝 古天龍
1 人固有能力的局限性以及使用工具后產生的力量
人類的勞動總的來說可以分為兩種:一種是體力勞動;另一種是腦力勞動。相應地,人的能力總的來說也可以分為兩種:一種是人體活動產生的力量,即體力;另一種是使用大腦產生的記憶、理解、想象等的能力,即腦力。
看看最能代表人的體力極限的世界紀錄(如跳高、舉重等),就可以很容易做出判斷,人的體力相當有限。然而,要人們承認這個事實卻很困難,各種小說,電影等更是極力地夸大人體的力量。
人的腦力也相當有限,因涉及記憶、理解、想象甚至與智力有關的問題,人們更難接受這個事實。
就體力而言,舉個例子,目前,跳高的世界紀錄是2.45米(1993年,古巴人哈維爾·索托馬約爾創造),而對一個普通的成年人,要想跳過1米的高度,并不困難?,F在,如果我們借鑒算法大O的表示,那么,顯然,世界冠軍與我們一般的成年人,其體力處在同一個數量級。
就腦力而言,要說人的能力處在同一個數量級更是讓人難以接受,然而,如果能像體育運動那樣明確比賽規則的話,就不得不接受人固有的腦力也處在同一個數量級的事實。比如,1加2加3一直加到N,規定必須一步一步相加,當N確定時,人們所花費的時間,不會相差太多,更一般的,當用同一個算法解決同一個問題時,不同的人所花費的時間,大致在一個數量級之中。換言之,在這種意義上,人的腦力處于同一個數量級。
既然人的體力和腦力極其有限,人固有體力和腦力又處在同一個數量級上,那又如何解釋人類在認知和改造客觀世界中所產生的巨大力量?答案在于,依靠工具,人能夠創造工具又能夠使用工具。
盡管人還未能跳過2.45米的高度,計算的速度也不快(智力本質上可以看作是一個認知過程,所有的智力過程,就時間而言,都是不可逆的、確定的計算過程,也就是一種計算),然而,若使用有形的工具,如飛機,人就可以飛得很高;使用無形的工具,如數學理論,就可以在較短的時間內,解決一些復雜的計算問題。
2 復雜性
根據信息論的觀點,復雜度可以定義為系統表明自身方式數目的對數,或是系統可能狀態數目的對數:K=logN,式中K是復雜度,N是不同的可能狀態數。一般來說,一個系統越復雜,它所攜帶的信息越多。若兩個系統各自有M個和N個可能狀態,那么,組合系統的狀態數目是兩者之積M×N,其復雜度為,K=logM×N。
從可操作性的角度,復雜性可以定義為:尋找最小的程序或指令集來描述給定的“結構”,即一個數字序列。若用比特計算的話,這個程序的大小相對于數字序列的大小就是其復雜性的量度。克拉默在其著作《混沌與秩序-生物系統的復雜結構》(Chaos and Order: The Complex Structure of Living Systems)一書中,給出了幾個簡單例子,用于分析相應程序的復雜性。
例1:序列aaaaaaa……
這是一個亞(準)復雜性系統,相應的程序為:在每一個a后續寫a。這個短程序使得這個序列得以隨意復制,不管要多長都可以辦到。
例2:序列aabaabaabaab……
與第1個例子相比,該例要復雜一些,但仍可以很容易地寫出程序:在兩個a后續寫b并重復這一操作。
例3:aabaababbaabaababb……
這個例子與例2相似,也可以用很短的程序來描述:在兩個a后續寫b并重復。每當第三次重寫b時,將第二個a替換為b。這樣的序列具有可定義的結構,有對應的程序來表示。
例4:
aababbababbbabaaababbab……
這個例子,無結構,若想編程,則必須將字符串全部列出。結論:一旦一個程序的大小與試圖描述的系統相提并論時,則無法編程。或者說,當系統的結構不能被描述,或描述它的最小算法與系統本身具有相同的信息比特數時,則稱該系統為根本復雜系統。在達到根本復雜之前,人們仍可以編寫出能夠執行的程序,否則,做不到。
3 軟件系統的復雜性
人固有的能力極其有限,但是,這種有限的能力可以用來創造工具和使用工具,最后產生巨大的力量。一個典型的使用工具的案例,就是阿基米德給出的一個利用杠桿原理的案例:給我一個支點,我就能撬起地球。
談到力學、物理學,就不得不提到一個近代科學的巨人,那就是牛頓。牛頓給出過一個著名的定律萬有引力定律。利用它,可以解決復雜的行星的軌跡問題。溫伯格(Gerald M.Weinberg)在其著作《系統化思維導論》(An Introduction to General Systems Thinking)一書中,對牛頓的貢獻進行了分析。他認為,牛頓是個天才,但他的才能并不在于他的大腦計算能力特別突出,而在于懂得如何對問題做合理的簡化和理想化,從而把復雜的問題轉化為普通人的大腦可以處理的、相對簡單的問題。牛頓是這樣,愛因斯坦其實也是這樣。
溫伯格的判斷是有道理的,然而,相對于物理學科,計算學科卻沒那么幸運,計算機的軟、硬件系統存在大量不能化簡的狀態,這就使得構思、描述和測試計算機系統,不能依靠像物理學那樣簡單的定律來完成,而必須另外尋找能夠控制和降低復雜性的方法。
在計算機中,軟件系統的狀態又比硬件系統的狀態往往要多若干數量級。另外,由于軟件系統中的實體,其擴展不像硬件系統那樣,可以由相同元素重復添加,從而使計算機中軟件的復雜度呈非線性增長。因此,找到控制和降低軟件復雜性的方法,也就找到了控制和降低計算機系統復雜性最根本的方法。于是,我們可以將問題的焦點放在計算機軟件上。
關于軟件的復雜性,布魯克斯(Frederick P.Brooks)在其著作《人月神話》(The Mythical Man-month)一書中,從復雜度、一致性、可變性、不可見性等方面作了系統地分析,揭示了軟件所固有的困難。下面,簡單闡述一下。
3.1復雜度
布魯克斯認為,沒有兩個軟件部分是相同的(至少在語句級別上),若有相同的,人們會把它們合并成一個供調用的子函數,因此,認為復雜是軟件的根本屬性。
軟件開發面對的是客觀世界模型的構建問題,相對于物理學,物理學家可以忽視大量實體內容的描述,僅僅關注諸如質量、速度等非常有限內容的描述,從而大大降低問題的復雜度,而軟件工程師卻不能這樣做。
構成軟件復雜度的實體及其關系的描述不僅引發了大量學習和理解上的負擔,而且隨著軟件規模的增長,使得團隊成員之間的溝通以及管理變得越來越困難,從而使軟件的開發逐漸地演變成一場災難。要避免這場災難,或者說,要順利地完成一個軟件系統的開發,其關鍵就在于能否控制和降低該軟件系統的復雜性。
3.2一致性
大型軟件開發中,為保持各子系統之間的一致性,軟件必須隨接口的不同、時間的推移而變化。這些變化不能被抽象掉,因此,又增加了軟件的復雜性。
3.3易變性
與計算機硬件、建筑、汽車等實體相比,軟件實體經常會面對持續的變更壓力。人們一般認為,已購買的計算機硬件、建筑、汽車等實體修改起來成本太高,于是打消了修改這些產品的念頭。而對軟件實體,人們卻不這樣認為,因為它是一個純粹思維活動的產物,可以無限擴展。
軟件處于用戶、法律、計算機硬件及其應用領域等各種因素融合而成的文化環境之中。該環境中的因素持續不斷地變化著,這些變化無情地強迫著軟件也隨之變化。
3.4不可見性
軟件是看不見的,當利用圖示方法來描述軟件結構時,也無法充分表現其結構,從而使軟件的復雜度大大超過具有電路圖表示的計算機硬件的復雜度,使得人們之間的溝通面臨極大的困難。
布魯克斯指出軟件復雜度是軟件生產的主要困難,不僅如此,他還分析了在軟件領域,人們所取得的進展,并且認為,這些進展只是解決了軟件復雜度的一些次要方面的問題,如果說有重大進展的話,那就是從匯編語言到高級語言的進展,其他的進展只能算是一種漸進。
的確如此,高級語言抽象掉了匯編語言所關心的寄存器、位、磁盤等概念,使軟件開發的生產率提高了若干倍,同時,軟件的可靠性、簡潔性也大為提高,相對于匯編語言,高級語言有效地降低了軟件的復雜性。
布魯克斯認為,對于一個軟件系統的開發來說,最為困難的是對其概念結構(概念模型)的規格、設計和測試,而不是對概念結構的實現,以及對這種實現的測試。當然,他也承認,在實現的過程中會出現語法的錯誤,但是,相對于概念結構方面的錯誤,則要小得多。
軟件系統開發的難點在軟件系統概念結構的規格、設計和測試上,因此,我們又可以將注意力更為集中。換言之,就是將重點盡可能放在軟件開發的前端,而不是編碼階段。
在軟件開發的前期,要對用戶的需求進行分析,然后,將這種需求抽象為一種信息結構,這種結構被稱為概念結構。其主要特點為:
(1)能真實、充分地反映現實世界,包括事物和事物之間的聯系,能滿足用戶對數據的處理要求;
(2)易于理解,從而可以用它和不熟悉計算機的用戶交換意見;
(3)易于更改,當應用環境和應用要求改變時,能容易地對概念結構進行修改和擴充;
(4)易于向計算機支持的數據結構轉換。
軟件概念結構的特點決定了這種結構的設計在很多情況下是很難采用形式化的方法,而采用非形式化的系統化方法,如結構化方法、面向對象方法等,卻可以有效地控制和降低概念結構設計的復雜性,最后,完成編碼、使軟件形式化。
系統化方法早已是大學“軟件工程”等課程的主要內容,而使用系統化方法的真正原因卻被人們忽視了,這樣做會使人們過高的估計自己有限的能力,從而削弱了人們自覺地應用系統化方法的基本原理去控制和降低軟件開發復雜性的巨大力量。
4 軟件開發的系統化方法需要遵循的基本原則
在軟件中,存在著大量不能簡化的實體,我們把這些實體稱之為元素,那么,軟件系統就是由這些相互聯系、相互作用的若干元素組成的,具有特定功能的統一整體。而軟件系統的概念結構則是指系統內各組成部分(元素和子系統)之間相互聯系、相互作用的框架。
在系統科學中,一個系統指的就是一個集合,或者說,指的是一個事物的集合。因此,我們可能用集合的思想來討論系統的復雜性。根據笛卡爾積,由兩個具有相互作用的元素構成的系統會有4種不同的狀態,而由10個元素組成的系統存在210=1024個狀態,64個元素組成的系統存在264個狀態,即18446744073709551616(比搬遷著名的Hanoi塔的次數多1)。隨著元素的不斷增加,系統必將出現“組合爆炸”的問題。對于這種“組合爆炸”的問題,不要說人所固有的極其有限的計算能力,就是計算機也無法處理。
笛卡爾積具有重要的理論價值,可以說,事物之間所有的關聯都在笛卡爾積之中。然而,人與機器對笛卡爾積產生的“組合爆炸”問題是無法進行處理的。因此,盡管笛卡爾積“完美無缺”,卻無任何實際的應用價值。因此,在實際工作中,我們還要充分運用與集合相關的函數、關系、定義等數學工具,將注意力放在事物之間具有實質性關聯的方面,最終控制和降低系統的復雜性。
對軟件的分析,可以從系統的角度,也可以從集合的角度來分析。因此,控制和降低軟件的復雜度的問題,就可以轉化為如何降低系統的復雜性,或更為基礎地如何降低集合復雜性的問題了。
要降低一個軟件系統的復雜性,就要將該系統劃分為若干小的子系統;類似的,要使一個大的、混雜的集合有序,就必須對它按某種性質進行分割,只有有序了,復雜性才能降下來,也才便于人們的理解和交流。下面,給出軟件開發的系統化方法需要遵循的幾個基本原則。
4.1 抽象第一的原則
所謂抽象,就是要對實際的事物進行人為處理,抽取所關心的、共同的、本質特征的屬性,并對這些事物及其特征屬性進行描述。由于抽取的是共同的、本質特征的屬性,從而大大降低了系統元素的絕對數量。
4.2 層次劃分的原則
如果一個系統過于復雜,以至于很難處理,那么,就得先將它分解為若干子系統。如何進行分解?什么樣的分解是一個好的分解?
我們知道,一個系統其實就是一個集合。那么,一個系統的分解,也就是一個集合的分解。在集合分解中,有一個叫等價類的重要概念,使用滿足等價關系的三個條件(自反性、對稱性和傳遞性),就可以將一個集合劃分為若干互不相交的子集(等價類),這樣的子集不僅具有某種共同性質的屬性,而且,還可以完全恢復到原來的狀態。這種劃分具有非常重要的意義,它可以使我們將注意力集中于子集中那些具有共同性質的屬性以及子集之間實質性的關聯,從而使無序變為有序,最終大大地降低系統的復雜性。
在計算機系統中,人們希望在層次的劃分中遵循等價類劃分的三個基本原則;另外,為便于記憶,還希望劃分后的層次數目控制在心理學中有關短時記憶最大容量7±2的范圍之內,像計算機網絡的層次結構、計算機的體系結構等均遵循這樣的原則。
4.3 模塊化原則
模型化原則就是根據系統模型說明的原因和真實系統提供的依據,提出以模型代替真實系統進行模擬實驗,達到認識真實系統特性和規律性的方法。模型化方法是系統科學的基本方法。
系統科學研究主要采用的是符號模型而非實物模型。研究系統的模型化方法,通常是指通過建立和分析系統的數學模型來解決問題的方法和程序。
用計算機程序定義的模型稱為基于計算機的模型。所有的數學模型均可轉化為基于計算機的模型,并通過計算來研究系統。另外,計算實驗對一些無法用真實實驗來檢驗的系統來說還是惟一可行的檢驗手段。
針對軟件,在考慮模塊化時,還要充分考慮來自Meyer給出的以下五個原則。
(1)模塊可分解性。要控制和降低系統的復雜性,就必須有一套相應的將問題分解成子問題的系統化機制,這種機制是形成模塊化設計方案的關鍵。
(2)模塊可組裝性。要充分利用現存的(可復用的)設計構件能被組裝成新系統,要盡可能避免一切從頭開始的模塊化設計方案。
(3)模塊可理解性。要使系統中的模塊能夠作為一個獨立的單位(不用參考其他模型)被理解,從而使系統中的模塊易于構造和修改。
(4)模塊連續性。在對系統進行小的修改時,要盡可能只涉及到單獨模塊的修改,而不要涉及到整個系統,從而保證修改后副作用的最小化。
(5)模塊保護。在模塊出現問題時,要將其影響盡可能控制在該模塊的內部,要使錯誤引起的副作用最小化。
5結束語
系統化方法針對的是復雜性問題,而復雜性又是相對于人的能力而言的。其實,人所固有的能力極其有限,然而,這種有限的能力可以用來創造工具和使用工具,從而產生巨大的力量。
系統化方法就是一類人們在生產過程中創造的有效工具,使用這種工具可以大大地降低軟件系統的復雜性,從而使軟件的研制處于某種可控的狀態。
系統化方法進入大學“軟件工程”等課程已有幾十年的時間,然而,使用系統化方法的真正原因往往被人們忽視。只有深刻理解軟件開發中使用系統化方法的真正原因,才能最大限度地增強人們使用系統化方法的自覺性和能動性。