1. 程式人生 > >論軟體設計中的哲學觀

論軟體設計中的哲學觀

 

        所謂哲學,即透過事物的表面現象,通過客觀理性的分析,找出更接近事物本質的通用解。從而以一種大宇宙的視角,來觀察和解讀這個世界的種種現象。如道家所謂的“一”,佛家所云的“眾生平等”。         軟體設計中的哲學觀,即以一種“一”的視角,來評價和反思我們的設計,來指導和改進我們的工作。從而達到一種雖手中無劍胸中卻有劍的境界,當如庖丁解牛,遊刃有餘。         第一次有人告訴我這個概念,是大約10年前,工作後的第一個導師,一個聰明偏執但讓人敬佩的華工怪才。當然那時初生牛犢,沒有什麼概念,憑藉與生俱來的一些小聰明和天生喜歡專研的精神,碰到再難的問題,腦海裡總會閃出各種idea。還曾以大學期間就有數萬行程式碼量而自大。因此多年在同學和同事中,也有一些還算過得去的小名聲。         那時候,我固執的認為,只要能圓滿解決工程中遇到的問題,用怎樣的方法根本不重要。所以總沉浸在有過多少多少程式碼量,解決過多少多少難題這樣的表面成就裡。         後來漸漸有了些經歷,就不得不開始對做過的一些事情加以總結和反思。雖然期間也做過一些自認為在業界都還算拿得出手的小創造,但似乎也總沒能跳出那一畝三分地,技術上也很難再有所突破。         後來就不斷的追問自己,當初為什麼選擇這個行業,需要的究竟是什麼?         這個行業說來戲劇,養活著世界上大多數最聰明的人,擁有一個巨龐大巨勤奮 同時“英年早逝”概率最高
的群體,吸引著無數對“高工資”誘惑缺乏抵抗力的年輕人,無數女孩眼中“技術宅“ 典型形象。         圈內人士卻喜歡用“碼農”自嘲,在這個物慾橫流的時代,沒有比“農民工”更傷自尊的措辭了。         不經箇中事不知其中味,有誰願意每天晚上10點都不 回家,有誰願意節假日沒有休息,更 不會有人願意凌晨3點被手機簡訊吵醒還不得不上線處理 各種伺服器宕機bug。         想想當年諾基亞3年研發一款功能極簡單的手機就可以暢銷5年,現如今半年研發一款最多隻能賣1年,功能還要強10倍,便知箇中辛酸和無奈。
        這是一個極度浮躁的行業,為快不破是這個行業亙古不變的生存法則。中國人的可怕之處在於,沒有信仰,所以不需要有道德底線。也因此敢想任何世人所不敢想,敢做任何世人所不敢做之事,只要能將對手打倒,可以不擇手段。         這個圈子永遠都不缺少發明輪子的牛人,當然更不缺少願意每天重複做著Ctrl+C和Ctrl+V來應對各種需求變更的“碼農”。可那又有什麼意義呢,當初前輩發明計算機的目的是解放人力,讓機器去幫我們做那些重複繁瑣的事,可如今我們卻反過來讓機器閒著,通過僱傭無數的“碼農”來做著重複繁瑣的體力活
        前段聽老闆講了一個有意思的段子,說有團隊想找他拉投資,一問只要300萬想都沒想就拒絕了,說敢開口要3000萬的話沒準還愉快的答應了。當然這個段子我等屌絲只當聽了一個笑話就過了。但回過頭來仔細想想,卻反映出行業的一個怪相,由於技術日趨開放和成熟,使得行業准入門檻越來越低。3個剛畢業的大學生,15個月,就能成就《刀塔傳奇》這樣月流水過億的傳奇手遊。在中國從來不缺有錢沒處砸的土豪,相比當年投資端遊5年耗資過億,也未必能聽見個響煤老闆們,這等成功案例該是有怎樣的誘惑力。         最近老在為招人的事情煩惱,半月間各種面試不下20人,我要求不算高吧,能腳踏實地做事就給及格。可讓我為這個行業的明天頗感擔憂的是,計算機科班出生的小本,什麼ACM,Unity3D,JavaScript,要什麼會什麼,可那些本該在學校打好軟體基礎呢?組合語言沒學過,資料結構不知道,什麼記憶體管理,編譯原理就更不用提了。         我想說的是,這種急功近利的思潮已經蔓延到學校,當下流行什麼技術就教什麼,等明天這些技術淘汰了呢,難道讓他們集體失業嗎?         誠然,隨著C/C++逐漸淡出,也許記憶體管理噩夢會漸漸的從普通程式設計師的日常工作中消失。可知其然不知其所以然,沒有練過馬步基本功的武術家,打起來怎麼都只能耍耍花架子。         說了這麼多,好像有點跑題了,言歸正傳,總之一句話,在不缺錢,不缺人,不缺裝置,不缺新技術的今天,我們究竟還缺什麼?缺少一種排除一切雜念,靜心把軟體本身做到極致的心境,缺少一種強迫自己慢下來的心態。         應用軟體開發商由於處於行業下游,為了爭取儘可能多的受眾群體,又不得不面臨一些商業競爭帶來的麻煩——要同時相容各種平臺,如Windows vs Linux,Android vs IOS,IE vs FireFox,VC vs  GCC等等等等。         不光如此,業務邏輯本身的需求也是千奇百怪。人是一種超有想象力的動物,就連只有一個領口兩個袖口的衣服,都能每天設計出幾千種不重樣的款式出來,就更別說已經深入全世界每個角落的軟體需求了。         不得不說,現代社會對軟體的期許,已經遠遠超出了這個行業的承載能力。現代軟體的複雜程度每天都在呈指數級增長,就連Iphone這樣的神機都會隔三差五的罷工,難道是Apple的工程師天生無能,所以寫不出一個沒有bug的作業系統嗎?所有的爛系統並不是生來就爛,多半是因為每天應對各種變態的需求變更被改爛掉的。         終於迴歸主題了,軟體設計中的哲學觀,就是為解決這些問題而被提出來的。         道家雲,“道生一,一生二,二生三,三生萬物”,看來我們真正需要的就是這個“道”。那麼何謂計算機的“道”?         當初前輩設計計算機的目的就是為了接替人類做那些重複繁瑣的工作。所以在硬體結構不做重大變革的前提下,計算機最擅長的就是處理那些重複性的工作(即軟體中常用的for),因為計算機是不知疲倦可以長時間不休息,並且不會像人那樣偶爾打個小盹開個小差。         在人工智慧機器人技術沒有實質性突破的前提下,計算機可以暫時認為是沒有創造能力,不能通過學習和經驗自己創造出解決新問題的方法,而只能機械的接受人們預先設定好的操作指令。因此可以認為,計算機最不擅長的恰恰是行為決策(即軟體中常用的if-else/switch-case)。         因此,所謂計算機的“道”,就是要在人的習慣和計算機的特性之間找到一個黃金分割點,讓“愚笨”的機器能夠秒懂“聰明的人類”發出的各種指令,即武術家常說的“人劍合一”,讓人和機器之間達到0成本溝通的境界。         縱觀人類和計算機溝通的手段——程式語言的發展史,從機器碼、組合語言,到C、C++、Java、Python、Lua、Golang、Shell,可以說人和機器溝通的成本是越來越低,因為思維模式越來越接近人的正常思維模式。可是我們卻漸漸的忽略了一個問題,由於人的惰性,總喜歡幹自己擅長的事,卻逐漸忽略了機器的感受。高階語言的表達能力一流,人們就習慣濫用指令碼,去強迫機器每天做自己所不擅長的事。         這裡不得不提的是,1943年出生於美國新奧爾良,同時是Unix和C語言之父的Ken Thompson(肯·湯普森),40年如一日,2001年從貝爾實驗室退休後,被大名鼎鼎的Google返聘,於2009年再次成為Golang之父之一。         大師手筆,絕非浪得虛名,Golang大道至簡的設計,可謂是大師們對“計算機哲學”的經典詮釋。語言層級天生的並行特性,極簡的語法,超強的表達能力,對OOP的經典表達,豐富的標準庫,高效的編譯和執行能力,無不讓後輩驚歎。         說完大師的經典作品,再看看“計算機哲學”對普通程式設計師的魔力。         可還曾記得《資料結構》課程裡那個關於單鏈表的經典實現嗎? 大師們為寫出乾淨清爽的程式碼,可謂煞費苦心。
//普通版本,m_pHead,m_pTail被初始化成NULL
void Slist:PushBack(Node* pNewNode){
        if(m_pTail != NULL){
                m_pTail->next = pNewNode; m_pTail = pNewNode;
         }else{ 
                m_pTail= pNewNode; 
        } 
}

//強化版本,m_pHead,m_pTail被初始化成DummyNode 。大師們為寫出乾淨清爽的程式碼,可謂煞費苦心。
void Slist:PushBack(Node* pNewNode){
        m_pTail->next = pNewNode; m_pTail= pNewNode; 
}

        用軟體設計中的哲學觀,來指導和評價我們的設計,需要遵循哪些原則呢?         1.解放人——讓他們做自己最擅長的事。         2.解放機器——讓它們做自己最擅長的事。         3.解放生產力——讓人和機器0成本溝通。         人在軟體設計過程中所扮演的角色和承擔的任務: 讀懂別人的程式碼,正確實現功能需求,長期維護功能程式碼以應對各種需求變更。         人的特點是:情緒化動物,喜歡每天嘗試新的東西,厭惡重複繁瑣的工作,會經常開小差犯錯誤,每天都需要多人合作,人員流動常態化,最擅長的是為各種千奇百怪的實際問題提出解決方案。         機器的特點是:最忠實的執行者,孜孜不倦最能勝任長時間不用休息的機械性重複勞動,沒有思想,不能用已有的經驗為新問題提出解決辦法,沒有決策能力,可以多機合作但也只是被動聽從指揮,就算明知道是錯誤的指令也會堅決執行。         所以,“計算機哲學”要解決的難題就是,讓人和機器這兩種性格迥異的參與者,愉快的合作,高效高質量完成千差萬別的日常實際需求。         那麼,符合怎樣條件的設計才能達到這樣的目的呢?         1.大道至簡—— KISS(Keep it simple and stupid)。             軟體產品最終是給機器去執行的,但更重要的還是,要給別人去讀懂的。沒有一個複雜的系統是能給所有人讀懂的,也沒有人願意去維護一個極度複雜的系統。             人是一種經常會開小差犯錯誤的動物,如何才能減少他們犯錯誤的機會呢,那就是程式碼量越少越好,修改起來越簡單越好。         2.高度模組化——高內聚低耦合。             軟體研發是要團隊合作才能完成的作品,那麼,團隊的每個人最終都只能分到系統中的一個小功能。那麼,怎樣才能讓每個人專心做好自己的工作,而不要停留在被別人打斷和不斷的打斷別人這樣的低效模式裡面呢?答案就是高度模組化的設計,事先只需要由架構師約定要模組之間的必要依賴,具體的實現交由各模組獨立實現,外部不做介面約定之外的任何約束。         3. 眾生平等—— 線性 擴充套件,跟if-else say goodbye。             世界是五顏六色的,每個人眼中的世界也是萬紫千紅的。這種現實對於人來說也許還有一定吸引力,但對於只擅長做重複性工作的計算機來說簡直就是個噩夢。計算機希望的世界原型是所有人都是兩隻眼睛一個鼻子,至於有的人大眼睛高鼻樑這種個性化元素是不希望去care的,而事實上這種個性化差異卻是客觀存在的,因此我們有了OOP,有了繼承,有了多型。讓計算機只看到所有人都是兩隻眼睛一個鼻子這樣的“一”,而允許不同的人去具體描繪出大眼睛高鼻樑這樣的“三”。從而從設計上達到“一”和“三”的和諧統一。         4.三生萬物——需求變更是每天都在發生的。             所有軟體的最終需求都不是一開始就完全定下來的,而是經過長期不停的變更改出來的。那麼,在最初設計系統的時候,都還不知道這些千奇百怪的新需求的時候,我們又該如何應對呢?從哲學的角度講,如果當初系統是在哲學原理框架下 設計出來的,萬變不離其中,猴子他再怎麼能折騰,也是難跳出這五指山。         侯捷老師曾戲稱,在STL面前,99.99%的人寫出來的資料結構演算法都是三流水準。那麼,在哲學原理視角下,我們每天寫出來的產品,也多半算三流水準。 軟體設計中的哲學觀,不能教會我們怎樣去設計一個一流系統,卻能指導我們如何設計出一個更合格的三流產品。