哲學家說:有什麼樣的世界觀,就有什麼樣的方法論!
辯論家說:立場決定觀點!
世界之所以有技術思想和觀點之間的爭論,完全與瞎子摸象的情境一樣。真理只有一個,但是卻很博大精深,沒有一
個人能看得到她的全部。每個追求真理的人都能感覺到她的存在,因為畢竟可以觸摸到她的一部分。於是,人們會發現自己摸到的部分是實實在在的,自然與其他人
不同,爭論難免。真理就像一個極限,我們永遠只能接近她,而不可能擁有她。軟體思想的發展也是一個不斷接近真理的過程。
剛開始有電腦程式的時候都是“面向演算法”的,人們為了充分發揮有限的硬體資源而設計出各種經典的演算法,“計
算機”就是用來計算的機器。但隨著硬體能力的提升與程式的複雜度增加,人們發現複雜的代碼難於閱讀和維護。於是,程式“結構化”的思想開始發展和成熟。
“把大問題分解成小問題來解決”是人類思維的習慣。冗長的代碼被分成若干的子過程,每個過程都便於理解,在此基礎上也就理解了整個程式。
其實,“面向演算法”與“結構化程式”都是以代碼為中心的世界觀,還是站在“電腦”的立場上。而當人們開始提
出“資料結構”思想的時候,才真正開始把思考轉向要解決的問題本身!人們越來越清楚地認識到,用資料結構去描述問題領域的模型,才是解決問題的關鍵,代碼
只是為資料服務的。從此,以資料為中心的世界觀開始逐漸形成。當然,“資料結構”是伴隨“結構化程式”的思想而發展的,這種思想的結合極大提升程式的編寫
效率,也提升了軟體生產率。
但這種思想還是將“資料”與“代碼”分開來思考的。事實上,在“物件導向”思想成熟之前,有經驗的程式員已
經感覺到“資料”與“代碼”應該是一體的。他們已經習慣將那些複雜的問題劃分為若干相對獨立的資料結構,並圍繞每個資料結構編寫一堆服務於該結構的子過
程,而過程的第一個參數就是一個結構的指標,這個指標就是人們熟稱的“控制代碼”,英文叫HANDLE。其實,這就是最原始的物件模型。當“物件導向”的思想
被提出的時候,我相信他們是最先理解此概念的一群人。
應該說“物件導向”的思想是第一次站在現實世界的立場上看問題,這種思想把人類思考問題的基本模式(如“分
類”,“抽象”,“普遍性與特殊性”)應用到軟體設計中。這種思想反映到編程上,就是將“資料”與“代碼”統一成一個“對象”,“對象”成為實現軟體的主
要方法。軟體思想發展到這時候有一點返璞歸真的感覺:原來可以用這樣簡單的思維方式去考慮複雜的軟體問題!
然而,隨著這種思想的深入應用,新的爭論又開始,但所有的爭論都已經是在另一個高度上。我想,在軟體思想上,最迷茫的應該是“繼承”與“組合”之爭。
由於人們太習慣“物件導向”的方法了,用基類來實現普遍需要的功能,派生子類來實現特殊性的東西。類的層次結
構就像一棵美麗的聖誕樹,真的很直觀。甚至,許多程式設計語言為了構造這棵美麗的聖誕樹而犧牲掉多重繼承的特性。但問題是,一旦這樣的繼承結構被固定下來,就
規定了系統的生長模式:只能長出新的枝葉!儘管,用類繼承模式設計出來的系統具有良好的擴充性,不過這種擴充是單向的。當要想在根基上擴充點東西的時候,
才發現這可能會動搖整個大樹!有的程式員試圖用多重繼承來解決這一問題,但切不說許多語言不支援多重繼承,如果真的能擴充一個基類,那麼你將面臨層次不同
的分支點,應該把哪些枝丫切開呢?
為此,一種稱為“介面”的軟體思想誕生了。“介面”思想提倡尊重對象的隱私,從來不去查一個對象的祖宗三代,
只要你能做事就行。每一件能做的事情都被定義為一個“介面”,一個對象對外的能力就是由它的那些“介面”組成,至於它怎樣做無關緊要。“介面”的編程思想
就是站在“功能組合”的立場上看問題,而不是來自父類的“功能繼承”。因此,對於“介面”思想來說,不管是基礎功能的增加還是的擴充新功能,都是擴充一個
介面而已,不再面對複雜的分支與階層。
“繼承”與“組合”僅僅是兩種看問題的方式。如果你喜歡豎著看世界,你會發現世界是“繼承”的。如果你喜歡橫著看,你會發現世界是“組合”的。
事實上,“面向方面”的思想就是橫著看世界。“面向方面”是“物件導向”思想的延續,是對“介面”編程的一種
理論總結。它把現實世界所有問題分解成需要解決的各個基本方面,即所謂的“橫向關切點”。這些基本面的問題解決是相對獨立的,而其組合起來就能解決全部問
題。當發現個別問題還有需要進一步解決的問題,可以在個別的局部範圍解決這個問題。而發現普遍要解決問題的時候,也可以給所有的對象增加另一個基本介面面
而加以解決,但不會影響其他已經解決的各個方面。
將來會不會有一種能夠統一“繼承”與“組合”的軟體思想呢?我想肯定有!而且新的思想和理論肯定會很容易被人們理解,人們又會發現世界原來如此簡單,也本該如此簡單!
在此給大家探討一個有趣的問題:
繼承的觀點認為,所有自然數的祖先是1;然後,2和3是繼承1的;但2和3是不同的;4具有2的特性,是從2繼承的;5既沒有2的特性也沒有3的特性,是直接從1繼承的;顯然6繼承了2和3的特性...
組合的觀點認為,任何自然數都含有1的成分,素數2、3、5、7是組成自然數的基本方面,其他的自然數都是由素數組合而成,所以稱為合數。
而大家都知道,任何自然數都可以因式分解為1與若干素數相乘,因此可以把1和素數看作自然數的原子特徵。如果
自然數B能被另一個自然數整A除,則表示B一定具有A的全部特徵(繼承思想),而構成A的質因子集合一定是構成B的質因子集合的子集(組合思想)。這是數
論的最基本常識,從這裡看問題,前面兩種思想是統一的。
值得注意的是,兩種觀點都承認1的重要性,而1就是幾乎所有進階的物件導向語言中都存在的那個Object,不管你是否願意它都存在。這就是Object存在的哲學依據!
但願將來一切軟體思想都這麼容易理解...
今天是2005年上班的第一天,在開始新一年的程式人生之前,僅以此文獻給和我一樣的所有程式員。
李戰(leadzen).深圳 2005-1-4