這幾年各種新的技術井噴一樣的湧現出來。身處這樣一個時代的我們,難免就有一種拔劍四顧,心下茫然的感覺。在某一方面的做到精專已屬不易,全才似不可能,那麼究竟又該何去何從?這篇文章目的是探討編程過程中一些本質的東西,已期對大家的學習有所幫助。
個人以為,從編程這一職業誕生開始一直至今,其本質就沒有改變過。對概念的抽象對邏輯的描述始終都是編程過程中最核心的東西。
程序為解決某一問題而存在。而問題可拆分成某些概念和邏輯關系。而結構化程序設計和面向對象程序設計不過是對概念和邏輯進行表達的不同方式。而程序中邏輯關系的復雜程度隨程序的規模而增加。
程序的本質不是各種技巧。就算你把EffectiveC++,MoreEffectiveC++中的每一條款都應用到了你的C++程序中,如果沒有對邏輯關系的良好組織,你的程序也可能糟不可言。可能高耦合低內聚,可能不可擴充―――。
上面這段文字提到了四個概念,他們分別是:問題、概念、邏輯和技巧。
我來舉個例子來說明這四個概念都代表些什麼。
現在假設我們需要根據已知的一個文件名產生一個臨時文件名。如果輸入為 prog.dat,mydir,hello.,oops.tmp,end.dat那麼相應的輸出為
prog.dat=>prog.tmp
mydir=>mydir.tmp
hello.=>hello.tmp
oops.tmp=>oops.xxx
end.dat=>end.tmp
(這裡使用了TheC++StandardLibrary中第11章的例子)
什麼都不做的程序是不存在的,程序總要解決客觀世界中的某些問題。這裡的問題就是要為一個已知的文件名產生相應的臨時文件名。
解決這個問題時涉及的概念主要有兩個:字符串和擴展名。擴展名可以用字符串進行表示。
解決這個問題的邏輯之一可用下面的偽代碼來表述:
if(輸入文件名沒有擴展名)
{
用輸入文件名、'.'號和"tmp"生成臨時文件名;
}
else
{
得到輸入文件名的擴展名;
if(擴展名為空)
{
用輸入文件名和"tmp"生成臨時文件名;
}
elseif(擴展名為"tmp")
{
把"tmp"替換為"xxx";
}
else
{
把文件名'.'以後的部分替換為"tmp";
}
}
當然你還可以有其他的實現邏輯,而這種邏輯總是可以獨立於語言、操作系統的。
至於你是用C++標准庫、還是MFC的Cstring類或者.net中的相應類或者不依靠類庫自己用某種語言來表述這種邏輯那就是技巧。
上面雖然是個小例子,但我認為完成任何程序:從上層應用直到底層驅動,都會涉及到這四個概念,。
上面所說編程時必須的四個要素中,我個人認為邏輯和概念是編程中更本質的東西,直接的原因是他們在更大的程度上決定著程序的質量。不要忘了評價軟件質量的幾個指標:
健壯性、可重用性、易擴充性、容錯性等。
而這些指標並不是你選擇了某個語言或者某個框架他們就達到了。而要通過對解決的問題的邏輯進行提煉和精化才可能達到。不要說這是系統分析的責任,程序每一部分都有自己要解決的問題,怎麼可能每一部分程序質量的保證都是系統分析的責任。
此外當你要把原來用軟件實現的功能換做用硬件來實現的時候,這點就分外的明顯--軟件其實就是一組邏輯關系。
但眼下主流意識形態似乎並不認同這點,各種招聘廣告可為明證。
下面是一個招聘軟件工程師的廣告:
1.BSdegreeoraboveincomputerscience.
2.Atleast2yearsofdriverdevelopmentexperience.
3.ExperienceinC,C++,windowsSDK/DDKorLinuxsystemdevelopment.
4.Familiarwithcomputernetworkingortelecommunication802.3,802.11,TCP/IPprotocolisaplus.
5.Familiarwithembeddedsystemdesign.
6.FamiliarwithBluetoothisaplus.
如果把編程與磨刀砍柴做類比的化,那麼
當某個人熟悉某種語言、某個框架、某個IDE、某個協議某個開發包的時候我們可以認為這個人擁有一把較鋒利的柴刀。但這和這個人最終擅不擅長砍柴並沒有然的關系。夫欲善其事,必先利其器。但利其器了未必就會善其事。所以說上面的廣告一定程度上相當於想找一個會砍柴的人,但看人的時候卻更注重他有沒有一把鋒利的刀子。(更可悲的是掙扎在生存邊緣的我們,縱然不願卻也不得不迎合這種要求)
未避免矯枉過正,這裡要強調一點,不是說基本技能不重要,沒有對語言、框架、IDE的一定認識,根本就產生不了有用的程序。但當我們執迷於對不同語言、框架、IDE的優缺點進行比較的時候,不要忘了他們並不對程序的健壯性、可重用性、易擴充性、容錯性等最終衡量程序優劣的諸多方面起決定作用。起決定作用的是你對概念的定義方式和對各種復雜邏輯關系的描述方式。
語言是什麼?語言是邏輯的載體和描述的工具。當你試圖表述邏輯關系的時候大多語言應該是滿足這一要求的,要不然他早被淘汰了。框架是什麼?框架是對邏輯和概念的一種封裝。框架把某一領域通用的概念和邏輯封裝起來,進而使程序員不必做一些重復性的工作。而實際上對這個領域的這些通用概念並不只有這麼一種表述方式,也就是說並不只有一種邏輯表述。你選擇某個框架的同時也就意味這你從n種方式中選擇了一種,捨棄了其他。沒有那個框架是完美的,選擇的同時自然也就繼承了這種不完美。所以善用他們,他們很重要,但不會再重要了。
當我意識到這點時,我發現雖然編程許久,但在對邏輯表述方面的能力卻沒有寸進,因為把90%以上的時間都投在了技巧的提升上了。JeffreyRichter和MattPietrek兩位堪稱Windows編程界中的技巧大師。可我現在敢說即使你把《Windows核心編程》、《ProgrammingServer-SideApplicationforMicorsoftWindows2000》還有MSDN雜志的UndertheHood專欄倒背如流,你可能還是寫不出高質量的程序。這些東西是必須的,但遠不是全部。
林銳寫過一本《高質量C++/C編程指南》,此書在網上流傳甚廣,我想原因有二:一是此書對C/C++語言中的容易造成模糊的地方進行了詳細說明(真的很有用);二是林銳筆法不錯。但也正因其流傳甚廣,我覺得在這裡必須指出,此書嚴重的文不對題。按照書中所說那些就能設計出高質量的C/C++程序麼?那些都是編程所需要的技巧,不過是告訴你怎麼能磨出一把鋒利的刀而已。如果讀過此書的人都把這些技巧和高質量的程序相等價,那麼學習時恐怕就難免會誤入歧途了。
這個題目太大,我是姑妄言之。這裡不過是剛剛開始一種探討而遠非結論。歡迎大家一起討論,還望諸君有以教我!