專訪範鋼:重構不是陽春白雪的高階玩意,而是碼農程式設計利器

Coding-lover發表於2015-10-13

CSDN:請先介紹下自己以及所從事的工作

範鋼:我是70年代生的人,在IT行業也算是一個老兵了。我這些年一路走來,從最初做小弟,然後當需求分析員、設計師,再後來帶著一幫小弟全國各地做專案。

掐指一算去過的地方還真不少:

  • 2006年,我們跟美女在湖南的鳳凰古城待著;
  • 2008年,在清晨靜謐的雲南撫仙湖裡泡澡;
  • 2009年,沐浴在西安古城的暮鼓晨鐘之中;
  • 2010年去了長白山天池;
  • 2011年上西藏布達拉宮,還去了聖湖納木錯;
  • 2012年,偶們又在青島喝啤酒、吃海鮮,享受靜謐的青島之夜;
  • 2013年,上天下第一險華山論劍去了。

豐富的經歷使我能夠站在不同的角度、比較全面地思考軟體研發方方面面的問題。

CSDN:作為一個IT老兵,你經歷過哪些技術變革以及學習過哪些語言?哪些經歷令你印象深刻?

範鋼:記得90年代末我還在學校讀書的時候,用的都是程式導向——諸如C、Fortran的程式語言。後來是VB,那時每天廢寢忘食研究VB的日子彷彿就在昨天。世紀的鐘聲敲響以後,我們都在使用PowerBuilder開發專案。那時你能想象1-2個人就能完成一個專案嗎?完成需求分析以後就開始資料庫設計,然後一天就可以設計N多DataWindow,一個月就能完成一個專案的研發。

我經歷的第一次重大的變革來源於2004年,當我從老家信心滿滿地來到北京時,突然發現我過去擅長的一切都變得無用了,我必須從頭開始,那是一種對未來無比的恐懼與無助。我不得不從頭開始學習Java,學習J2EE,學習三層結構。後來eclipse出來了,放棄了JBuilder;Spring Frameworks出來了,放棄了EJB……現在,正在經歷由傳統架構轉變為網際網路與大資料的大變更中。

CSDN:你是如何看待這些變革以及對應的語言?

範鋼:經歷那麼多變故,發現變故不可怕。這個行業的特性就是這樣,總是在變。與其遲疑不定,不如從心裡去接受它,然後先人一步去變,它會給你更多的淡定與自信。

如今,我開始放棄Java學習Scala。我突然發現,所謂技術,有時候就像一部時尚大片。10年前,我們不得不放棄那些function開始物件導向程式設計;經歷10年的輪迴,如今我們開始放棄笨拙的物件,進行函數語言程式設計。但經過10年我們是不是又回到了原點呢?其實不是的,我們的技術開始在螺旋式地盤旋上升。

CSDN:每次的技術變革基本都要求你從頭開始,在快速學習以及心態調整上有什麼和大家分享嗎?

範鋼:與其被動地懼怕變革,不如欣然地去面對變革。多看書、多上CSDN看部落格、刷論壇,就會讓你的頭腦總是保持新鮮。你應當保持一顆好奇的心,對什麼新技術,總想一探究竟。Redis出來了,用一用;Spark出來了,學一學。你不必樣樣精通,但必須見識廣博。還有就是,要學就學主流的,非主流的要學會放棄,做一個技術界的時尚達人。因此,有一些圈子,認識一些牛人還是蠻重要的。他們不一定能給你解答難題,但卻可以給你最新的資訊,讓你始終站在技術最前沿,去學習最該學習的東西,從而讓自己也成為一個牛人。

CSDN:從業這麼多年,什麼的專案對你幫助最大?

範鋼:要回答這個問題,大家先思考一下另一個問題:如果有一個人,一生都很順利,沒有經歷什麼挫折,做什麼成什麼,那麼這是“完美人生”嗎?我認為恰恰相反,這不是完美人生,他的缺憾就在與他沒有經歷失敗。我們不希望失敗,但對於每個人來講,失敗往往給你的幫助是最大的。“常在河邊站哪有不溼鞋”,誰沒有經歷過失敗的專案,然而正是這些失敗的專案對我幫助才是最大的,它讓人一夜從男孩轉變成男人。最關鍵是,不要去遺忘和逃避失敗,而是要正視與總結失敗。

2011年經歷了我職業生涯最大的打擊,陷入了人生最大的低谷。由於沒有做好專案管理與客戶溝通工作,被撤銷了專案經理職務。我們每個人忘掉過去的痛苦與失敗都是容易的,但要真正面對失敗去分析與總結,才是勇敢與不斷進步的表現。因此從這年的9月開始,我陸續發表了系列文章《一次迭代式開發的研究》,站在更加實踐的角度去探討專案管理的風險與應對的措施。從此一發不可收拾,寫了不少膾炙人口的系列文章。

重構不是陽春白雪的高階玩意,而是碼農的程式設計利器

CSDN:對重構,大家的理解可能都有所不一樣,你對重構是怎麼理解的?

範鋼:有人認為重構是陽春白雪的高階玩意兒,我卻認為它是我們尋常D絲的程式設計利器,讓設計方面乏善可陳的我們,也能寫出高質量的程式碼;有人認為重構是必須到無藥可救時才能放出來的終極大招,我卻認為它是一開始程式設計就應當養成的程式設計習慣,程式設計→重構→優化,不斷迴圈這個過程才是優秀程式設計師必備的素質。專案經理總把重構當成洪水猛獸,但它真的是專案經理的親密夥伴,它讓軟體專案從惡性迴圈走向良性迴圈,重新煥發生機。

總之,只有學好重構,才能成為一名真正優秀的程式設計師和技術管理人員。

CSDN:進行重構,應該遵循什麼原則?

範鋼:重構不是大家想象的那種暴力改程式碼,也不是通常認為的那種推倒重來,重構是要按照一定的科學方法與步驟進行。

  • 首先,在修改程式碼時應當運用重構方法進行重構,這些方法都是一個一個的等量變換,它能保證重構前與重構後的程式程式碼功能完全一致,從而實現安全重構;
  • 其次,重構是從原有程式碼開始,一小步一小步的修改程式碼,每改一次10-30分鐘,然後執行除錯,通過測試用例進行驗證,這個過程被稱為“小步快跑”;
  • 另外,重構是不改變軟體的外部行為的,所以可以在重構前先建立測試用例,能跑通原程式,那麼在以後的重構過程中,能夠跑通同樣的這些測試用例,重構就是正確的,以此來驗證重構的正確性;

記住,重構是不可能一步到位的,應該從簡單開始,一步一步改造,一點一點優化程式碼。

CSDN:有人說,重構應避免過度思考,你對這句話怎麼看?

範鋼:是的,重構應避免過度思考,這裡的過度思考就是,將幾步併為一步,在某一步驟的重構中思考過多,過快地進行重構。

大家知道,不論做什麼事情,都應當遵循一定的章法來做事,而那些自作聰明、將幾步併為一步的做法常常會適得其反,重構也是這樣的。“小步快跑”的開發模式,就是要求我們在重構過程中,一步一步、循序漸進地進行重構。在每個重構週期中,不要想得太多,僅僅只採用一個重構方法來進行重構。這樣做一方面容易檢驗我們重構過程的正確性,一旦重構出錯,可以快速定位問題原因,解決問題,恢復正常,提高開發的效率;另一方面保證我們思路的清晰,避免我們因思考得過多、過於複雜而顧此失彼、帶來新的BUG,給重構工作帶來風險。

一次只採用一個重構方法,這說得容易,但常常在實際工作中,在運用這個重構方法時,同時想到了別的重構,這該怎麼辦呢?我們在完成了此次重構以後,很可能就忘掉了那個重構!這時,一個好的習慣就是拿著一個小本隨時記錄下這靈光一現的思路,然後在完成每次重構以後不斷去check out那些記錄。這樣,既避免了過度思考,又保證這些想到的重構步驟在日後都能夠及時回憶並予以完成。

CSDN:其實重構是一個事後補救措施,一旦重構就需要浪費大量時間和精力成本,因此你認為開發者應該養成什麼樣的習慣才能儘量地避免重構。

範鋼:正所謂“積少成多,金石為開”,我們需要浪費大量時間和精力成本去重構,是因為我們欠的技術債太多了。如果我們每次程式設計都是遵循著“編碼→重構→優化”的步驟去做,或者每次需求變更時都按照“兩頂帽子”的思路先重構程式碼以適應新的需求,再變更,重構真的就不是一個事兒。但是現在我們已經欠了那麼多債了,怎麼辦呢?是不是我們就應當大範圍的大搞重構呢?其實往往不是這樣的。

按照我的經驗,越是大張旗鼓地重構越容易失敗,越是從實用角度出發、從小處去重構越容易成功。什麼叫“從小處出發”,就是著手思考和優化你經常要調整的程式碼,總在修改並且越改越彆扭的程式碼。從函式級別、從物件級別,用最小的代價去重構你最急迫需要優化的程式碼,你越容易取得成功。

CSDN:重構並非萬靈藥,你認為在什麼情況下不應該去重構?

範鋼:重構是一種習慣,當我們在編寫程式碼時應當採用“小步快跑”的方式,先用最簡單的方式讓程式碼跑起來,然後遵循著“編碼→重構→優化”的方式一點一點往裡面新增新的功能和程式碼;當需求變更時,運用“兩頂帽子”的方式先重構再變更。但所有的重構都是面向著那些我們在不斷變更和調整著的程式碼。但如果我們的某些程式碼沒有發生變更,執行得好好的,我們為什麼要去重構它們呢?我們還是省省力氣吧,千萬別過度重構。

CSDN:有人說重構是架構師、技術大牛的事,和普通程式設計師無關,對此你怎麼看?

範鋼:重構是架構師、技術大牛的事,也是普通程式設計師的事,只是站在的層次不同。重構分為程式碼級別的重構、元件級別的重構與系統級別的重構。普通程式設計師關注得更多的應當是程式碼級別的重構,它讓我們可以去優化我們的函式、方法、類的設計;架構師與技術大牛關注的則是系統級別的重構,它考慮的則是如何系統地去調整軟體的架構,即分層結構與技術框架,從而適應未來市場的變化與技術的革新。

那麼,不同級別的重構都應當怎樣做呢?這些在我的新書《大話重構》中都有所探討。

只要有好的程式設計習慣,小白也能寫出高質量程式碼

CSDN:你怎麼看待高質量程式碼和重構之間的關係,為什麼?

範鋼:要弄清這個問題,讓我們先弄明白什麼在制約我們高質量的程式碼。過去我們有一個誤區,就是認為高質量的程式碼設計要在編碼之前做很多的設計,考慮很多可能的變更,做出很多靈活的設計。然而,我們不是先知,我們不知道未來會有什麼樣的變更,因而我們走向另一個極端——過度設計。

其實我們真的不用那麼焦慮未來的變更,因為我們有重構。用最簡單而清晰的設計實現當前的功能就是高質量的程式碼。然而,為什麼我們的程式碼經過幾輪的變更以後質量就開始下降?那是因為我們的軟體在隨著需求的變更而變得越來越複雜。簡單軟體有簡單軟體的設計,複雜軟體有複雜軟體的設計。當簡單軟體隨著需求的變更變為了複雜軟體時,我們還在簡單軟體的設計上強行新增程式碼,軟體質量就開始下降。因此,採用“兩頂帽子”的方式,先重構程式碼以適應新的需求,再變更,就能讓我們的軟體重新回覆高質量的程式碼。因此,我認為,重構是實現高質量程式碼設計的一個捷徑。

CSDN:那高質量的程式碼如何實現呢?

範鋼:要實現高質量的程式碼其實很簡單,就是養成一種好的程式設計習慣,即使剛畢業的小白也能做到的:

首先,在編寫新的程式碼時,應當學會採用“小步快跑”的程式設計方式。簡單來說就是,先從整體上進行一些設計,忽略掉很多分支與細節,用最快速而簡單的方式編寫第一個版本,讓程式迅速跑起來。然後一小步一小步地重構程式碼,不斷往程式中新增功能,新增分支與判斷,不斷完善與豐富功能,執行、測試、優化。這樣,系統就像小樹苗一樣一點兒一點兒成長,最後變為參天大樹。在這個過程中,我們總是能夠執行、能夠驗證正確性、能夠不斷優化,就能保證程式碼的高質量。 
其次,當需求變更到來時,一定不能就著原有的程式結構簡單的往裡面新增程式碼,這是程式碼退化的罪惡之源。根據需求分析現有的程式結構,對其進行調整,該增加可擴充套件點的增加可擴充套件點,該程式碼複用的將需要複用的程式碼提取出來。只有當我們正確完成了程式碼重構以適應新的需求以後,再實現新的功能,才能真正讓需求變更不會帶來程式碼的退化。這個過程就是重構中所說的“兩頂帽子”。

正是因為有了重構,從大的環境上進行了保證,才能讓我們在今後的編碼與變更過程中,該擴充套件的擴充套件,該複用的複用,該解耦的解耦,再輔之以相關設計模式與設計原則的學習,從而真正實現高質量的程式碼編寫,讓剛畢業的小白不再是專案經理的痛。

CSDN:能對“小步快跑”的程式設計方法舉幾個例子嗎?

範鋼:“小步快跑”的程式設計方法,是一種高效的程式設計方法,它摒棄了那種“完備的設計→完備的編碼→完備的測試”這種近乎於瀑布式的開發模式。“小步快跑”的程式設計步驟通常是這樣:

  1. 忽略掉所有的細節與分支,用最簡單快捷的方式完成主流程的編寫,讓程式快速跑起來;
  2. 以重構的方式不斷往程式中新增新的功能,每次新增新的功能都應當足夠短小而可以快速實現,從而通過測試快速檢驗新增的功能;
  3. 不斷往復步驟2,直到完成開發。

為了說明這種程式設計方法,讓我們用實際工作中的一個案例來進行講解吧:

為了讓案例儘量貼近工作,又不給大家帶來業務知識的障礙,我們來看看一個資料推送程式的實現過程。該程式的需求就是將一個資料庫中的資料推送給另一個資料庫,一方面應當能夠高效處理大量資料,讓推送方與接收方有效解耦,另一方面應當能夠實現字符集轉換、執行過程的監控以及方便快捷地定義新的推送介面。當你接到這樣一個需求的時候,你是怎樣去分析和設計的呢?

顯然,這個簡單功能所要達到的預期目標很多:高效處理大量資料、讓推送方與接收方有效解耦、實現字符集轉換……要一一實現確實需要很多的設計。但採用“小步快跑”的方式,起初你並不需要想那麼多。首先從巨集觀上制定出技術方案,即先採用一個高效的方式匯出資料檔案,再用一個高效的方式匯入到目標資料庫。制定出這樣一個技術方案以後,我們就可以動手程式設計了。

動手程式設計時,不要想那麼多,首先編寫一個簡單的匯出程式,SQL是固定的,引數也寫死。就一個目標:能跑通,第一個版本就形成了。

在此基礎上開始我們“小步快跑”的重構之旅了(注意:每完成一步都要測試與驗證):

  1. 編寫一個模板,讓SQL是可變的,引數也可以配置;
  2. 在模板的基礎上,讓SQL與引數都配置在後設資料表裡,通過配置這些表就可以快速地定義一個一個的資料推送介面;
  3. 開始編寫匯入程式,在編寫時發現可以大量複用匯出程式的程式碼,故而重構匯入程式,將公共部分抽取介面或工具類,從而實現程式碼複用;
  4. 完成簡單的匯入程式並跑通後開始改寫,通過模板與後設資料實現推送介面的可配置;
  5. 實現各個過程的日誌編寫,以及目標資料庫的對賬校驗功能;
  6. 實現各個過程的異常處理,以及系統級的異常資訊採集;
  7. 完善各個部分的程式碼命名與註釋;
  8. 重新思考與調整各個功能的分層與解耦。

CSDN:你對需求分析怎麼看?你後來還提出了“客戶需求可行性分析”理論,能大概介紹其關鍵點嗎?

範鋼:這些年做了那麼多軟體專案,有成功的、有失敗的,真的切身感受到,需求分析的成功與否,非常關鍵地決定了一個專案的成功與否。無數令人絕望的專案都是始於不到位的需求分析。然而,在實際工作中,我們的需求分析工作既低效又無所適從。通過這一系列的文章,我點出了需求分析工作問題的核心,那就是被動式的需求分析,即客戶說什麼就是什麼,一切都以客戶說的為準。客戶往往是非技術的,因此客戶提出的需求往往也是非常理想而難以實現的。用這樣的需求去指導開發,結果可想而知。

正確的做法應當是主動式的需求分析,即跳出客戶需求的本身去主動學習與理解客戶的業務領域,分析客戶需求背後的動機,從而站在更加深刻的角度去理解客戶的需求,然後結合技術實現去分析客戶需求隱藏的問題,這就是所謂的“客戶需求可行性分析”,即分析客戶需求是否可行。最後,站在客戶的角度去探討其中的問題,同時提出更加可行的方案。

這裡的關鍵問題就在於我們對客戶業務領域的理解到底有多深。我們對業務領域理解得越深,我們對客戶需求的理解就越深,分析的問題也就越深,與客戶探討的過程中就越能被客戶認可,從而提出為客戶認可與接收的技術方案。這樣的方案,既準確表達了客戶的需求,又可以在技術上是可行的。按照這樣的方案設計開發軟體專案,才能真正有效地規避需求方面的風險。這種思路在實踐中得到了許多的成功,並且讓無數的網友腦洞大開。

CSDN:什麼是過度設計?應該如何避免?

範鋼:過度設計,是因為設計者擔心日後的變更,擔心日後變更時現有設計無法應付,因而做出的當前需求不太需要的可擴充套件點或者一些靈活設計。這些設計雖然可以應付日後的變更,卻是要付出成本的,它會加大軟體的複雜度,降低系統執行效率。如果這些設計日後用上了,這種成本是值得的,但如果沒有用上,你不僅沒有獲益,還需要為之買單,其實是非常不划算的。所以,在我看來,任何事情只有化繁為簡,我們才能做得更好,才能從容應對。

不論你在設計還是重構,都不要想得太多,想得太長遠,因為你不是先知。“活在今天的格子裡,做今天的事兒”。那麼未來變更了該怎麼辦呢?當變更時,運用“兩頂帽子”,先重構系統以適應新的需求,再變更,那麼什麼狀況你都能應付了。到那時,所有那些可擴充套件點與靈活的設計,都是後移到變更時才做出,就可以有效避免軟體的過度設計。

沒靈感時,請放空自己

CSDN:在平常工作過程中,是否遇到一些難纏的問題,導致一時半會無法解決的,這個時候,你們都是如何應對,重新煥發“靈感”? 

範鋼:在IT這個行業所有的人都很勤奮,這是我們都優點。但我希望我們要做的不僅是十分勤奮的程式設計師,還應當是充滿智慧的程式設計師。一個充滿智慧的程式設計師,不應當是那種埋頭苦幹的程式設計師,而是將更多的時間用來思考那些精妙設計的程式設計師。

因此,當我在平常工作中遇到了難纏的問題,一時半會無法解決、想不清楚、拿不出好的方案的時候,我往往的選擇是放下手裡的活兒乾點兒別的。倒杯水、喝個咖啡、散散步,抑或是寫個文件、做點兒別的事情。當你將手裡的活兒、現有的思路忘得一乾二淨的時候,再重新回來工作,很可能就會迸發出新的火花,產生新的思路,冒出新的解決方案,重新煥發出靈感。很多創新的設計就是這樣出來的。記住,在IT這樣一個充滿創新與智慧的產業裡不要去做一個埋頭幹活兒的工兵。

CSDN:請給我們程式設計師朋友推薦重構、架構方面的書籍吧?

範鋼:重構方面最經典的毫無疑問就是那本《重構,改善既有程式碼的設計》,它是軟體重構的理論基礎與入門書籍。這本書雖然闡述了“重構”這樣一個重要的概念,卻不能幫助我們很好地在工作中去實踐,而這正是所有重構者最頭痛的事情。正因為如此,看一些重構實踐的書籍對大家是很有幫助的,Robert C Martin寫的《程式碼整潔之道》和《敏捷軟體開發:原則、模式與實踐》在程式碼級別的重構方面都是不錯的選擇,而埃文斯寫的《領域驅動設計:軟體核心複雜性應對之道》則在系統級重構方面可以給我們很多的借鑑。此外,《大話重構》是我奉獻給大家的一本嘔心力作,也能給大家一些幫助。

軟體架構方面,溫昱寫的《軟體架構設計》、人郵出版的《恰如其分的軟體架構》和馬丁·富勒的《重構與模式》都是不錯的書籍。作為一個優秀的架構師,不是僅僅技術好就可以了,而是要擁有很好的大局觀與前瞻性才可以。這些書籍都可以很好的擴充你的思路與視野,從而站在一個更高的角度看待一個系統。

CSDN:對於當下的中國軟體產業,你有什麼思考或建議嗎?

範鋼:當下的中國軟體產業,用“浮躁”二字來形容一點兒不為過。人們追逐新技術、開拓新市場,這毋庸置疑。但是,在嘗試一個一個的新技術,推出一個一個的新產品的同時,很少有人真正去關注那些軟體內部的質量。那些管理者不關注軟體質量,他們關注的是新產品的開發進度;那些有經驗的程式設計師也不關注軟體質量,他們雖然掌握著豐富的經驗與軟體技術,卻帶頭寫著糟糕的程式碼,讓剛畢業的新生們情何以堪。缺乏卓越品質追求的中國軟體產業,就像一個缺乏深厚內力的武者,很難在激烈競爭的軟體市場上走得更遠,走得更堅實,這就是中國軟體產業的現狀。

因此,作為中國軟體產業中有責任的一員,我們應當更加關注軟體的品質,更加關注軟體設計這門技術。我們應當將軟體設計當成一門藝術,每一次程式設計都應當去精雕細琢。只有軟體品質上去了,我們的軟體企業才會走出小作坊,在這個激烈競爭的產業中佔據一席之地。而“重構方法”、“小步快跑”、“兩頂帽子”則是我為大家找到的,快速實現這個目標的最佳實踐與有效捷徑。

CSDN:最後想問下你:是什麼因素促使你現在進入大資料分析領域?

範鋼:眾所周知,軟體產業是所有產業中變化最大的一個產業,每隔三、五年就會完成一次改朝換代。在我看來,這個產業未來發展的趨勢必然是網際網路、大資料與移動應用。這三個趨勢得其一則得天下。在我以往的專案經歷中,在基於資料分析的防欺詐與風險控制方面,具有豐富的經驗。這些經驗為我現在進入大資料分析領域打下了堅實的基礎。如今我嘗試進入企業大資料徵信領域,期望在這個領域中闖出一番新的天地。

轉載自:http://www.csdn.net/article/2015-09-22/2825775

相關文章