抽象:程序員必備的能力

2015年大熱的動畫片《動腦特工隊》中描述了這麼一個場景, 冰棒帶領樂樂和憂憂抄近路去乘坐思維列車,所謂的“近路”就是穿過抽象思維的房間,在這個房間裏, 他們先是變成了變成3D的塊,就像計算機圖形學裏展示的那樣:

然後變成平面的圖形

最後只剩下一些線條了 !

真是非常生動的展示了人類做抽象活動的過程。

在軟件業,抽象能力的重要性怎麼說都不爲過,因爲軟件開發是一個高度複雜的智力活動,程序員經常需要面對、處理異常複雜的業務和邏輯,如果你不具備強大的抽象能力,無法把具體變成概念,進而駕馭概念進行思考, 你就很難降低問題的複雜度,從而陷入泥潭,無法自拔。
無論你學會了多麼強大的程序語言,你的編程能力也很難有質的提高。

當然抽象不僅僅是軟件開發的獨有概念,在別的領域可以看到更多,例如帝國經常提的“三. 個. 代. 表”,“和. 諧”(當然現在已經變成貶義詞了),“中. 國. 夢” ,就是把執政理念和民衆的訴求進行抽象,當然實施的效果如何就留給大家評說了。

在自然科學領域,抽象的例子更多,開普勒定律和萬有引力就是很典型的例子。

在16世紀很多人開始相信哥白尼提出的日心說,但一直搞不清楚圍繞太陽的行星到底是怎麼運動的,軌道是什麼樣子,著名天文學家開普勒仔細的研究了他的老師 –傑出的觀測家–第谷留下的大量天文觀測數據以後, 提煉出了著名的開普勒三定律, 第一次給出了天體運行規律的解釋:

  1. 所有行星分別是在大小不同的橢圓軌道上運行
  2. 在同樣的時間裏行星向徑在軌道平面上所掃過的面積相等
  3. 行星公轉週期的平方與它同太陽距離的立方成正比

開普勒三定律從大量的數據中提煉出數學規律, 無疑是非常偉大的發現和抽象, 但這不是最終本質,當然也不是最終的抽象。

行星運動的本質是萬有引力定律。

相比於開普勒定律,天才的牛頓所做的抽象向前邁進了一大步,萬有引力幾乎覆蓋了所有大質量物體之間互相吸引和運動的規律, 即簡單又優美, 配合牛頓(和萊布尼茨)發明的微積分,可以很容易推導開普勒定律。

如果再加上牛頓力學三定律,尤其是F=ma , 整個經典物理學的架子就建起來了,後人所有的工作只是在這座大廈上進行一些裝修工作,直到愛因斯坦相對論的出現,才建立一座更宏偉的大廈。

據說愛因斯坦在評價一個研究時,會用美和醜來作爲判斷標準,有人拿研究成果讓愛因斯坦看, 愛因斯坦不說成果的好與壞,反而說“這東西多醜陋啊”, “這東西真漂亮”。

其實一個抽象的東西形式優美,結構簡單,很有可能是正確的,很可能抓住了事物的本質。

相反如果連形式都醜陋不堪,十有八九不是好的成果。 以此作爲標準,萬有引力定律無疑是漂亮的,正確的,當然愛因斯坦的E=mc2 更加漂亮和簡單。

抽象的例子在軟件業更是數不勝數:

文件是對I/O的抽象;
虛擬存儲器是對物理存儲器的抽象;
進程是對一個正在運行的程序的抽象;
我們再增加一個新的抽象:虛擬機, 他提供了對整個計算機(包括操作系統,處理器,程序)的抽象。

Andorid 把一個移動應用程序抽象成Activity , Intent, Service,Provider。
……
稍微注意一下就會發現: 抽象層次越高,接口的語意就越模糊,適用的範圍就越廣,到最後就會變成數學模型或者概念。
數學模型和算法
我認爲把紛雜的事物抽象到數學層面是最高的抽象,也許會有人會說哲學層面纔是:-) ,但到數學層面已經非常難了。尤其是重大的科學發現,身後必然有數學的影子。

牛頓當年爲了描述天體的軌道和運動,特別創立了新的數學表示: 微積分

麥克斯韋使用一組方程對電場和磁場行爲進行描述。

當年愛因斯坦腦海中已經有了廣義相對論,但苦於找不到合適的數學形式來描述,他特別花了幾年的時間來學習非歐幾何和張量分析,最後才得以成功。

海森堡用矩陣理論來解釋量子力學
。。。。

程序員在開發過程中, 也許能把一個實際的業務問題抽象成數學模型,或者抽象成特定的算法,這樣會讓程序實現變得非常簡單和有趣。

我在之前的公司有幸遇到過一次,把針對稅務領域的一個Credit, Debit等概念抽象爲在一個二維座標下點的運動, 問題一下子簡化了很多,實現簡單,並且非常安全可靠。
正交的概念
但是抽象成數學模型和算法通常是可遇而不可求的, 這種情況下,我們需要退而求其次,試圖抽象成若干個正交的概念,來降低複雜度。

“正交”在數學上指的是線性無關,最常見的例子就是座標系下的x 軸和y軸,對於一個點來講,它的x值的變化不會影響到y, y值得變化不會影響到x ,即x和y是正交的。

正交的威力在於互不影響,擴展方便,單用一個座標軸可以表示一個直線上的所有的點, 再加一個y 軸就能表示平面上的所有的點, 再加一個z軸 3維空間中的所有點都能表示出來了!

我們人類的大腦在思考問題的時候是有容量限制的, 難以同時駕馭太多負責的概念, 如果我們的軟件系統也能做成x,y,z 座標這樣,就帶來了無與倫比的好處,你在處理x軸相關的事情時,不用考慮其他的y和z 相關的東西,因爲你知道他們不會受到影響, 這樣問題的複雜度就從3維一下子下降到1維!更容易把握了。

如果單單x 軸仍然很複雜,你要做的就是再次分解成更小的概念,保證正交即可。
接口
如果你說了,我的整個系統還沒法抽象成正交的概念, 那隻好再退一步,在局部使用接口。

在著名的《設計模式》一書中,其實在反覆強調一點: 發現變化並且封裝變化,針對接口編程而不是實現編程。 很多人看書是隻關注具體的模式,而忽略了模式的本質目的。

我們在開發的過程中要保持一種敏銳的感覺,發現可能的變化並且封裝起來,只提供一個精心定義的接口讓外界調用。這樣你在接口後面所做的任何變化,外邊就不受影響了。

例如在JDK中Iterator 就是一個很好的抽象, 它將集合本身和集合的遍歷分開。 Stream 抽象也不錯,封裝了對文件和網絡操作,只是使用起來稍顯麻煩。

其實 一組定義良好的接口一定是正交的,不然的話接口之間的依賴就會讓實現非常麻煩。

總結
說到底,軟件設計和開發就是把現實中的問題映射的計算機的語言實現,但現實問題太複雜,細節太多,而且在不斷的變化過程中,一般人很難同時對這麼的細節進行思考 ,這時候就需要抽象。

我們只有從紛繁複雜的現象中抽取事物的本質,從具體事物提煉出正交的概念,才能駕馭這些概念,才能在一個低複雜度的世界中進行思考。

抽象能力的高低,很大程度上反映了一個程序員的能力的高低

公衆號:碼農翻身
“碼農翻身”公衆號由工作15年的前IBM架構師創建,分享編程和職場的經驗教訓。
作者 劉欣 來源 碼農翻身公衆號 鏈接:http://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513062&idx=1&sn=a3b4a2962d8e82471192d9606b0a2722&scene=21#wechat_redirect

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章