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