|
知止而后有定,定而后能靜,靜而后能安,安而后能慮,慮而后能得。 ——《大學》
從寫第一個x86程序算起,到現(xiàn)在,轉眼也已有十年。變量、數(shù)組、指針、引用、函數(shù)、命名空間、封裝、繼承、多態(tài)、GP、接口、元數(shù)據(jù)、反射、FP、DRY、TDD、SOA、WF、LINQ、AOP、DI、LOP ...... 在一條充滿了無數(shù)HelloWorld、被拋棄的想法、寒夜孤燈以及工程實踐"血淚史"的道路上,我從一個同學年少變成了奔三程序員"大叔",并且依然義無反顧地向前狂奔著。直到剛剛那一刻,我才突然回過頭,望著那條已經(jīng)不太能夠看得清起點的來時道路,心生一念:是否應該先停一停,作些不同以往的思考?我為何而來?要向何處去?
什么是寫程序?為什么寫程序的過程是這樣的?這樣寫程序是正確的嗎?這樣寫程序是唯一正確的方式嗎?現(xiàn)在,我的工作生活中很大一部分時間都是在寫程序;在可以預計的將來,我也不太可能依靠開洗浴中心來討生活。所以我認為認真思考這些問題對我的人生應該是很有幫助的,而對于那些在類似的道路上前行的朋友們,即便不能起到拋磚引玉的作用、達到無心插柳的效果,至少也可以添作飯后茶余一笑。
好!那么就先停一停,讓我們的視線穿過紛繁蕪雜的名詞,回到那個一切開始的地方——程序。
按照編程趣味讀物的慣例寫法,時間應該回到19XX年的一個夏夜,年輕的我正為了某個重要的理由在某某平臺上用某某開發(fā)工具寫一個叫某某某的程序,接下來就會若有所思地感慨過去2009減19XX年間世道變了許多。但是,事實上我當時正在用VB6為一個同班漂亮女生寫著很蹩腳的五子棋游戲(帶有“很炫”的splash screen),這個例子顯然不夠滄桑與深刻,所以讓我們跳過感慨直入主題。
牛人說:人類文明運行于軟件之上。竊以為:寫程序便是要把人類的意識固化到計算機當中,讓這些文明與智慧能夠反反復復地運行下去。程序其實并不是在描述客觀世界,而是在描述人們對客觀世界的認識。如果意識是物質的模型,那么程序就是意識的模型。也許這種二階模型的構造、變更與驗證存在著固有的復雜性——寫程序或者更具體地對我而言,開發(fā)與維護企業(yè)軟件系統(tǒng)相對于吃泡面來說是一件很困難的事情。對于絕大多數(shù)困難的事情,不同領域的天才們都曾經(jīng)給出驚人相似的解決方案——分治復用。面對強大的敵人,我們首先要保存自己,接著忽悠最廣大人民群眾并尋找革命同志,然后奮力挖墻腳,進而剪除頑固不化的死忠,斷水斷電斷煤氣,最后直搗黃龍,這就叫分治;前事不忘,后事之師,面對頻繁的需求變更與一個接一個嶄新的項目,如何能夠避免每次都"重新制造車輪",盡量利用已有的開發(fā)成果并且使當前的開發(fā)成果能夠被今后的項目利用,這就是復用。分治是復用的先決條件,復用是分治的最終目標。我所能想起的最早的復用,應該就是 jmp 了。沒錯,是個匯編指令。雖然這個指令也用來構造條件分支,但是開發(fā)人員確實由此獲得了免于重復輸入相同代碼的能力,只要在適當?shù)臅r候重新跳回起始地址就好了。此后,goto、do-while、foreach、函數(shù)、封裝、繼承、Component、RPC、WebService ... 使得我們可以穿透各種系統(tǒng)邊界在不同的層級上復用已經(jīng)存在的實現(xiàn)。同時我們還應該注意到實現(xiàn)復用之外的另一條主線:接口復用。封裝、多態(tài)、接口、契約、依賴注入等等技術讓我們能夠在系統(tǒng)中引入更多的抽象,使得高層代碼能夠獨立于那些可能會發(fā)生變化的具體實現(xiàn),始終保持不變。當我們懷著庖丁解牛的理想,以復用為最終目的,使用分而治之的策略將系統(tǒng)拆分成很多足夠細小的抽象概念與具體實現(xiàn)步驟時,一個問題產(chǎn)生了:是什么把這些層層疊疊的部件裝配到一起構成了整個系統(tǒng)?換言之,程序代碼到底是什么?答案可以高度概括為一個正則表達式——[_A-Za-z][_A-Za-z0-9]*,沒錯,開發(fā)人員使用標識符給系統(tǒng)的任何一部分起名字,實例、屬性、方法、事件、類、接口、命名空間、JNDI、DI id ... 在排除了那些流程控制語句和元素聲明的寫法等等在同一個程序語言中固定不變的內容之后我們發(fā)現(xiàn),任何程序,無論采用何種編程范式,都是由一堆按照固定順序和方式出現(xiàn)標識符組成的,其中每一個標識符都代表了一個內存地址或者另外一堆標識符。采用不同的編程范式似乎只是在影響高層標識符的意義與組織方式。排除接口復用方面的考慮不談,如果OB或者OO相對于過程式編程而言還存在其他優(yōu)勢的話,那么主要就體現(xiàn)在前者提供了構造良好分治結構的可能性,封裝、繼承、接口等技術就像一個黃頁分類系統(tǒng),如果設計良好可以讓用戶快速定位目標;而過程式編程的開發(fā)成果永遠是扁平的。 隨著系統(tǒng)復雜程度的增加,OO必然也會遇到相同的問題,即如何有效的組織系統(tǒng)的各個部分,讓開發(fā)人員可以更容易地根據(jù)需求進行代碼定位,使得所有關于復用的努力能夠真正實現(xiàn);而不是因為引入了過多的抽象層次讓系統(tǒng)變得難以理解,最終導致開發(fā)人員明明知道可以復用的實現(xiàn)就在這里,卻因為陡峭的學習曲線而不得不再次重新制造車輪。
一段典型的現(xiàn)代OO代碼片段是這樣的:
OO code
這說明我們每天寫程序的人的生活也是這樣的:拿到一個需求;自己琢磨、Google、MSDN、API Doc、Community或者問一圈同事才找到一些對象;逐一弄清楚上邊那些所有的What、WhatYet 以及 WhatElse 都代表了些蝦滅;編譯測試調試編譯測試調試編譯測試調試;直到我們真正的弄清楚了那些所有的What、WhatYet 以及 WhatElse 都代表了些蝦滅 ...... 每個公司的開發(fā)流程可能不同,但是具體到代碼簽出之后到簽入之前的這段繁復的手工操作我想應該還是大同小異的。即使這個框架是你一手設計的,你可以完全理解所有的抽象概念,那么對于一個新加入團隊的員工呢?對于十年之后已經(jīng)不太記得當初那些精心安排的工巧的你呢?
就在這里停下吧!難道我許多年來傾注了滿腔的熱情,遵循著分治復用的原則,接受了諸多概念、技術、信仰與習慣,最后獲得的日常生活就是這樣的重復查找與驗證么?我本可以用來記憶更多家人朋友消息或是八卦娛樂新聞的大腦存儲空間必須要被征用過來,把那些晦澀的標識符及其出現(xiàn)順序倒背如流么?!
不!我相信生活不應該是這樣的。我相信寫程序的最終目的應當是為了終結寫程序;在OO之外,在現(xiàn)有的編程范式、模式與最佳實踐之外一定還有其他更好的辦法能夠提高程序代碼的生產(chǎn)效率、進一步解放千千萬萬像我一樣的人——程序員。
(待續(xù))
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。