Martin Thompson是Java Champion稱號獲得者,同時也是一名高性能計算科學家。他說,為了寫出更好的代碼,程序員需要運用基本設計原則,閱讀已有代碼。在QCon London 2016大會上,他做了題為“挖掘你的工程師屬性(Engineering You)”的演講。InfoQ在會后采訪了他,內(nèi)容涉及軟件行業(yè)面臨的挑戰(zhàn)及程序員如何應對那些挑戰(zhàn)成為更好的軟件工程師。
InfoQ:您在演講中引用了1968年第一屆NATO大會上有關軟件工程的一些內(nèi)容,它們?nèi)匀怀闪ⅰ\浖袠I(yè)為什么還是在苦苦掙扎?
Martin Thompson:1968年的NATO大會有好幾個主題。他們認識到,軟件行業(yè)存在交付危機。他們也看到了一些成功的項目,并且希望弄清楚如何吸取好的經(jīng)驗,進行更廣泛地應用。在我看來,其中有幾點比較突出,就是認識到軟件開發(fā)是一個迭代過程,注重試驗/學習,需要專門人才領導,并且最好是在小型團隊內(nèi)完成。他們在幾十年之前就從許多方面描述了TDD和敏捷這些在當時并不常見的做法。
作為一個行業(yè),我們已經(jīng)取得了很大的進步,但是我們?nèi)匀挥泻荛L的路要走。軟件開發(fā)是一個非常年輕的學科,我們?nèi)匀挥泻芏鄸|西要學。我喜歡Dijkstra對它的描述,“煥然一新(radical novelty)”,而使用一些很不恰當?shù)碾[喻和類比,會注定我們的失敗。軟件構(gòu)建是在之前活動基礎上的躍變。這些活動和約束與之前的活動截然不同。有些人有這方面的天賦,有些人需要學著做,而大多數(shù)人很掙扎。在土木工程學方面,我們耗費了幾個世紀才具備了現(xiàn)在的能力,因此也就不奇怪軟件行業(yè)當前的掙扎。
InfoQ:您為什么認為理解基本設計原則,如耦合和內(nèi)聚,很重要?
Thompson:軟件開發(fā)面臨的其中一個最大的挑戰(zhàn)就是處理應用程序規(guī)模增長帶來的復雜性。對象、組件、模塊或系統(tǒng)之間的耦合程度越高,我們需要承擔的后果就越多。這些后果包括但不限于修改困難、故障蔓延、由于爭用而無法擴展、由于關聯(lián)操作而導致的性能問題。時間、空間和實現(xiàn)上的松耦合對于擴展性和彈性而言至關重要?!肮采裕–onnascence)”可以很好地描述耦合,一個模塊/組件的變化會導致另一個模塊/組件的變化。
我發(fā)現(xiàn),內(nèi)聚比耦合更微妙。我喜歡將內(nèi)聚理解為統(tǒng)一性。當我們考慮在不同的方面使用同一個組件時,就失去了統(tǒng)一性,這會導致不必要的行為和特征。軟件設計中的低內(nèi)聚常常是一個很好的需求或團隊狀況指標。通常,內(nèi)聚設計很容易跟蹤,由于相關的函數(shù)和特性都進行了分組,相互關聯(lián),所以可發(fā)現(xiàn)性很高。
如果我們希望成為更好的軟件工程師,那么提高我們運用基本設計原則的技能應該成為我們?nèi)粘;顒拥暮诵?。在訓練和實踐中不斷重復是讓技能成為第二天性的最好方法。
InfoQ:您能舉幾個例子說明下,如何運用分解和抽象幫助開發(fā)人員寫出更好的軟件嗎?
Thompson:我認為,抽象是軟件開發(fā)領域被人誤解得最深的話題之一。Dijkstra將抽象描述為一種創(chuàng)建“新的語義層次”的方式,“在這個語義層次中,一個人可以做到絕對精確”。大多數(shù)開發(fā)人員都完全是亂用這個術語,創(chuàng)建他們所謂的抽象來掩飾他們不懂的東西。Joel Spolsky甚至發(fā)明了“抽象泄露(leaky abstractions)”原則,拙劣地想為這種誤解正名。我們有些很棒的抽象示例,如Linux內(nèi)核或設備驅(qū)動中的塊設備,但遺憾的是,大多數(shù)軟件抽象通常是源于某種形式的精神自慰,導致弗蘭肯斯坦怪獸的誕生,讓代碼更難以處理,而不是更嚴密更容易理解。糟糕的抽象比重復的成本更高。
我們需要更擅長將業(yè)務目標分解成可衡量的具體成果,然后以高質(zhì)量、低耦合的可組合組件為基礎構(gòu)建軟件。商業(yè)公司希望我們在他們的框架內(nèi)完成構(gòu)建,那樣他們可以鎖住客戶。這些框架是錯誤的示范。它們是商業(yè)壓力催生的產(chǎn)物。商業(yè)壓力與交付高質(zhì)量的可維護軟件往往是矛盾的。
如果看一下其他工程學科,我們就會看到,工具的使用是為了支持交付流程,而不是強加一個流程。我們似乎展現(xiàn)了這個時代的一個特征,商業(yè)廣告聚焦于人天價格、per-CPU許可及鎖定維護合同?,F(xiàn)在,類似Amazon這樣的公司提供了實用計算,讓我們可以根據(jù)需要使用。非常有趣的是,云計算很好地支持了持續(xù)集成和交付模型。這改變了市場格局,推動了更好的行為。我們也可以從工具方面看待這個問題,類似Jetbrains這樣的公司將你鎖定在他們的產(chǎn)品合同上;他們是通過提供可以提高生產(chǎn)力的優(yōu)秀產(chǎn)品把你鎖定的。
InfoQ:您提到,把重讀代碼作為發(fā)現(xiàn)缺陷或改進代碼的方式。您能詳細地闡述下嗎?
Thompson:任何創(chuàng)造性的嘗試都可以從不斷地審視和完善中受益。你曾經(jīng)回過頭來閱讀已經(jīng)寫好的郵件、論文、博客或報告等等,然后覺得某些部分可以做得更好呢?這是一件很自然的事情。當我們回過頭來看時,情況不同了,我們會有新的認識。從最簡單的層面來說,我們的寫作初衷已經(jīng)從我們的短期記憶中消失了,我們必須真正的重讀和思考。換句話說,我們有了更多的信息,世界發(fā)展了,我們的知識也豐富了。
我喜歡將代碼視為一個可以捕獲當前看法的地方。我們都會犯一些回過頭來看時可以糾正的錯誤,除了糾正這些錯誤外,我們還可以記錄我們更深入的理解。一般而言,應用程序是業(yè)務流程的軟件模擬。如果軟件沒有捕獲當前了解的業(yè)務流程,那么開發(fā)人員就必須做一個心理映射。在任何項目中,心里映射都是一個很大的負擔。這是我認為領域驅(qū)動設計是一個重要的軟件開發(fā)工具的原因之一。
定期閱讀所有的代碼,而且不只是你自己的代碼。閱讀他人的代碼是一種很棒的學習方式。正如作家Stephen King所言,“讀其他人的書是讓你成為一個更好的作家的最好方式?!边@同樣適用于代碼,開源是我們這個行業(yè)采取的最好的措施之一。通過公開開發(fā)軟件,我們可以分享理解,獲取反饋,向其他人學習。參與開源是讓你成為一名更好的工程師的最佳方式之一。