抽象指的是從紛繁複雜的事物中提煉本質的過程,是乙個具體到概念的過程, 例如蘋果、香蕉、生梨、葡萄、桃子等,它們共同的特性就是水果。得出水果概念的過程,就是乙個抽象的過程。
在軟體業,抽象能力的重要性怎麼說都不為過,因為軟體開發是乙個高度複雜的智力活動,程式設計師經常需要面對、處理異常複雜的業務和邏輯,如果你不具備強大的 抽象能力,無法把具體變成概念,進而駕馭概念進行思考, 你就很難降低問題的複雜度,從而陷入泥潭,無法自拔。 無論你學會了多麼強大的程式語言,你的程式設計能力也很難有質的提高。
當然抽象不僅僅是軟體開發的獨有概念,在別的領域可以看到更多,例如帝國經常提的「三. 個. 代. 表」,「和. 諧」(當然現在已經變成貶義詞了),「中. 國. 夢」 ,就是把 把執政理念和民眾(或者利益集團)的訴求進行抽象,雖然實施的不怎麼樣。
在自然科學領域,抽象的例子更多,克卜勒定律和萬有引力就是很典型的例子。
在16世紀很多人開始相信哥白尼提出的日心說,但一直搞不清楚圍繞太陽的行星到底是怎麼運動的,軌道是什麼樣子,著名天文學家克卜勒仔細的研究了他的老師 --傑出的觀測家--第谷留下的大量天文觀測資料以後, 提煉出了著名的克卜勒三定律, 第一次給出了天體執行規律的解釋:
1. 所有行星分別是在大小不同的橢圓軌道上執行
2. 在同樣的時間裡行星向徑在軌道平面上所掃過的面積相等
3. 行星公轉週期的平方與它同太陽距離的立方成正比
下圖展示了第一定律和第二定律
克卜勒三定律從大量的資料中提煉出數學規律, 無疑是非常偉大的發現和抽象, 但這不是最終本質,當然也不是最終的抽象。
行星運動的本質是萬有引力定律。
相比於克卜勒定律,天才的牛頓所做的抽象向前邁進了一大步,萬有引力幾乎覆蓋了所有大質量物體之間互相吸引和運動的規律, 即簡單又優美, 配合牛頓(和萊布尼茨)發明的微積分,可以很容易推導克卜勒定律
如果再加上牛頓力學三定律,尤其是f=ma , 整個經典物理學的架子就建起來了,後人所有的工作只是在這座大廈上進行一些裝修工作,直到愛因斯坦相對論的出現,才建立一座更巨集偉的大廈。
插曲:據說愛因斯坦在評價乙個研究時,會用美和醜來作為判斷標準,有人拿研究成果讓愛因斯坦看, 愛因斯坦不說成果的好與壞,反而說「這東西多醜陋啊」, 「這東西真漂亮」。
其實乙個抽象的東西形式優美,結構簡單,很有可能是正確的,很可能抓住了事物的本質。
相反如果連形式都醜陋不堪,十有**不是好的成果。 以此作為標準,萬有引力定律無疑是漂亮的,正確的,當然愛因斯坦的e=mc2 更加漂亮和簡單。
抽象的例子在軟體業更是數不勝數:
unix 把所有的裝置都抽象成檔案的概念,把程式之間的互動用抽象為「管道」。
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 抽象也不錯,封裝了對檔案和網路操作,只是使用起來稍顯麻煩。
其實 一組定義良好的介面一定是正交的,不然的話介面之間的依賴就會讓實現非常麻煩。
總結
說到底,軟體設計和開發就是把現實中的問題對映的計算機的語言實現,但現實問題太複雜,細節太多,而且在不斷的變化過程中,一般人很難同時對這麼的細節進行思考 ,這時候就需要抽象。
我們只有從紛繁複雜的現象中抽取事物的本質,從具體事物提煉出正交的概念,才能駕馭這些概念,才能在乙個低複雜度的世界中進行思考。
抽象能力的高低,很大程度上反映了乙個程式設計師的能力。
抽象 程式設計師必備的能力
抽象指的是從紛繁複雜的事物中提煉本質的過程,是乙個具體到概念的過程,例如蘋果 香蕉 生梨 葡萄 桃子等,它們共同的特性就是水果。得出水果概念的過程,就是乙個抽象的過程。在軟體業,抽象能力的重要性怎麼說都不為過,因為軟體開發是乙個高度複雜的智力活動,程式設計師經常需要面對 處理異常複雜的業務和邏輯,如...
抽象 程式設計師必備的能力
2015年大熱的動畫片 動腦 隊 中描述了這麼乙個場景,冰棒帶領樂樂和憂憂抄近路去乘坐思維列車,所謂的 近路 就是穿過抽象思維的房間,在這個房間裡,他們先是變成了變成3d的塊,就像計算機圖形學裡展示的那樣 然後變成平面的圖形 最後只剩下一些線條了 真是非常生動的展示了人類做抽象活動的過程。在軟體業,...
程式設計師必備能力 晉公升之道
從我認識的程式設計師中,包括我的團隊中,有不少很久都沒有晉公升過。他們維護著已經再熟悉不過的模組,能迅速定位bug所在 行數,在他們當中有部分人熱愛coding,享受debug帶來的成就感,但是絕大部分的程式設計師並不是他們熱愛,而更多的是被迫。你們有認識這樣的人嗎?我想你肯定已經在點頭了,這種情況...