知止而後有定,定而後能靜,靜而後能安,安而後能慮,慮而後能得。 ——《大學》
從寫第乙個x86程式算起,到現在,轉眼也已有十年。變數、陣列、指標、引用、函式、命名空間、封裝、繼承、多型、gp、介面、元資料、反射、fp、dry、tdd、soa、wf、linq、aop、di、lop ...... 在一條充滿了無數helloworld、被拋棄的想法、寒夜孤燈以及工程實踐"血淚史"的道路上,我從乙個同學年少變成了奔三程式設計師"大叔",並且依然義無反顧地向前狂奔著。直到剛剛那一刻,我才突然回過頭,望著那條已經不太能夠看得清起點的來時道路,心生一念:是否應該先停一停,作些不同以往的思考?我為何而來?要向何處去?
什麼是寫程式?為什麼寫程式的過程是這樣的?這樣寫程式是正確的嗎?這樣寫程式是唯一正確的方式嗎?現在,我的工作生活中很大一部分時間都是在寫程式;在可以預計的將來,我也不太可能依靠開洗浴中心來討生活。所以我認為認真思考這些問題對我的人生應該是很有幫助的,而對於那些在類似的道路上前行的朋友們,即便不能起到拋磚引玉的作用、達到無心插柳的效果,至少也可以添作飯後茶餘一笑。
好!那麼就先停一停,讓我們的視線穿過紛繁蕪雜的名詞,回到那個一切開始的地方——程式。
按照程式設計趣味讀物的慣例寫法,時間應該回到19xx年的乙個夏夜,年輕的我正為了某個重要的理由在某某平台上用某某開發工具寫乙個叫某某某的程式,接下來就會若有所思地感慨過去2009減19xx年間世道變了許多。但是,事實上我當時正在用vb6為乙個同班漂亮女生寫著很蹩腳的五子棋遊戲(帶有「很炫」的splash screen),這個例子顯然不夠滄桑與深刻,所以讓我們跳過感慨直入主題。
牛人說:人類文明執行於軟體之上。竊以為:寫程式便是要把人類的意識固化到計算機當中,讓這些文明與智慧型能夠反反覆覆地執行下去。程式其實並不是在描述客觀世界,而是在描述人們對客觀世界的認識。如果意識是物質的模型,那麼程式就是意識的模型。也許這種二階模型的構造、變更與驗證存在著固有的複雜性——寫程式或者更具體地對我而言,開發與維護企業軟體系統相對於吃泡麵來說是一件很困難的事情。對於絕大多數困難的事情,不同領域的天才們都曾經給出驚人相似的解決方案——分治復用。面對強大的敵人,我們首先要儲存自己,接著忽悠最廣大人民群眾並尋找革命同志,然後奮力挖牆腳,進而剪除頑固不化的死忠,斷水斷電斷煤氣,最後直搗黃龍,這就叫分治;前事不忘,後事之師,面對頻繁的需求變更與乙個接乙個嶄新的專案,如何能夠避免每次都"重新製造車輪",盡量利用已有的開發成果並且使當前的開發成果能夠被今後的專案利用,這就是復用。分治是復用的先決條件,復用是分治的最終目標。我所能想起的最早的復用,應該就是 jmp 了。沒錯,是個彙編指令。雖然這個指令也用來構造條件分支,但是開發人員確實由此獲得了免於重複輸入相同**的能力,只要在適當的時候重新跳回起始位址就好了。此後,goto、do-while、foreach、函式、封裝、繼承、component、rpc、webservice ... 使得我們可以穿透各種系統邊界在不同的層級上覆用已經存在的實現。同時我們還應該注意到實現復用之外的另一條主線:介面復用。封裝、多型、介面、契約、依賴注入等等技術讓我們能夠在系統中引入更多的抽象,使得高層**能夠獨立於那些可能會發生變化的具體實現,始終保持不變。當我們懷著庖丁解牛的理想,以復用為最終目的,使用分而治之的策略將系統拆分成很多足夠細小的抽象概念與具體實現步驟時,乙個問題產生了:是什麼把這些層層疊疊的部件裝配到一起構成了整個系統?換言之,程式**到底是什麼?答案可以高度概括為乙個正規表示式——[_a-za-z][_a-za-z0-9]*,沒錯,開發人員使用識別符號給系統的任何一部分起名字,例項、屬性、方法、事件、類、介面、命名空間、jndi、di id ... 在排除了那些流程控制語句和元素宣告的寫法等等在同乙個程式語言中固定不變的內容之後我們發現,任何程式,無論採用何種程式設計正規化,都是由一堆按照固定順序和方式出現識別符號組成的,其中每乙個識別符號都代表了乙個記憶體位址或者另外一堆識別符號。採用不同的程式設計正規化似乎只是在影響高層識別符號的意義與組織方式。排除介面復用方面的考慮不談,如果ob或者oo相對於過程式程式設計而言還存在其他優勢的話,那麼主要就體現在前者提供了構造良好分治結構的可能性,封裝、繼承、介面等技術就像乙個黃頁分類系統,如果設計良好可以讓使用者快速定位目標;而過程式程式設計的開發成果永遠是扁平的。 隨著系統複雜程度的增加,oo必然也會遇到相同的問題,即如何有效的組織系統的各個部分,讓開發人員可以更容易地根據需求進行**定位,使得所有關於復用的努力能夠真正實現;而不是因為引入了過多的抽象層次讓系統變得難以理解,最終導致開發人員明明知道可以復用的實現就在這裡,卻因為陡峭的學習曲線而不得不再次重新製造車輪。
一段典型的現代oo**片段是這樣的:
oo code
iwhatyet whatyet
=null
;try
catch
(whatexception e)
return
whatyet;
這說明我們每天寫程式的人的生活也是這樣的:拿到乙個需求;自己琢磨、google、msdn、api doc、community或者問一圈同事才找到一些物件;逐一弄清楚上邊那些所有的what、whatyet 以及 whatelse 都代表了些蝦滅;編譯測試除錯編譯測試除錯編譯測試除錯;直到我們真正的弄清楚了那些所有的what、whatyet 以及 whatelse 都代表了些蝦滅 ...... 每個公司的開發流程可能不同,但是具體到**簽出之後到簽入之前的這段繁複的手工操作我想應該還是大同小異的。即使這個框架是你一手設計的,你可以完全理解所有的抽象概念,那麼對於乙個新加入團隊的員工呢?對於十年之後已經不太記得當初那些精心安排的工巧的你呢?
就在這裡停下吧!難道我許多年來傾注了滿腔的熱情,遵循著分治復用的原則,接受了諸多概念、技術、信仰與習慣,最後獲得的日常生活就是這樣的重複查詢與驗證麼?我本可以用來記憶更多家人朋友訊息或是八卦娛樂新聞的大腦儲存空間必須要被徵用過來,把那些晦澀的識別符號及其出現順序倒背如流麼?!
不!我相信生活不應該是這樣的。我相信寫程式的最終目的應當是為了終結寫程式;在oo之外,在現有的程式設計正規化、模式與最佳實踐之外一定還有其他更好的辦法能夠提高程式**的生產效率、進一步解放千千萬萬像我一樣的人——程式設計師。
(待續)
第一天寫古詩詞錄
開篇第一篇,首先說明一下我的部落格裡為什麼會有這個欄目 此時的我一邊聽著由陳悅 馬克合奏的 岫壑浮雲 一邊寫這篇文章,我不會說那種出口富麗堂皇 詩詞滿篇 滿嘴絕世經綸的話,毫不虛偽的說,我是一名大專生,高考失利,無奈選了乙個跟it行業毫不搭邊的學校,經過了一番執著的學習,終於才有了今天的現在的我,我...
通訊錄 第一版番外篇
define crt secure no warnings 1 ifndef addressbook h 使用條件編譯,防止重複引入標頭檔案 define addressbook h define name max 20 define max 6 define tele max 20 define ...
程式設計師自省錄
前言 本文具有批判性,如有誤解請移步右上角叉叉。為什麼做程式設計師?我相信每位入行的童鞋 除了高工資,有免費大桶水喝的辦公室,不幹體力活的各種原因外 都有想用 改變世界的想法。我也是這樣,在苦苦掙扎了五年後,我發現我並未成功改變世界,而是讓 改變了自己。為什麼要做程式設計師?是對程式的熱愛,對 的忠...