我們程序員應該是工程師

我是開發人員還是程序員? 也許是代碼忍者或黑客? 我在LinkedIn上的個人資料大膽地宣稱我是一名"技術專家",我當時認為這是一個很酷的職業頭銜,而且可能不會自動讓我擔任任何特定角色。 在我的職業生涯中,我花更多的時間編寫代碼和維護系統的時間,使我更加相信我應該依靠從工程學科的經典根源中汲取的原理和哲學。

我們程序員應該是工程師

> Photo by Dan Meyers on Unsplash

就像以前我們心愛的NYC地鐵運輸工程師一樣,他們不會設計一個系統來關閉整個線路的電源,以替換第三部分的單個部分,軟件開發人員負責創建系統,可以適應所需的更改並維持維護。如果我們使用技術不可知性和可衡量的術語(例如耦合程度)來描述風險並衡量技術債務償還期內的風險降低,則企業領導者將我們視為專業工程師而不是忍者黑客的機會將會增加。與不存在使類或函數安全的耦合度的絕對規則幾乎相同,不能保證我們經過仔細衡量的風險分析將引起關注,但我們應增強這種思想和分析的能力。它將鼓勵人們理解其他未知的風險,並且隨著時間的流逝,將導致更易於維護和適應的系統。對於那些由程序員轉為工程師的程序員,您將更好地準備親自接受對我們社會最終依賴的系統的影響的責任。

我已經看到"爆炸半徑"一詞越來越流行,主要是圍繞安全性和網絡體系結構(例如,每個服務模型一個雲子帳戶),除了它固有的暴力色彩外,我喜歡它。 當發生意外事件時,您的組織中有多少需要做出反應? 好吧,我答應過一些可衡量的項目,我認為有兩個密切相關的概念將對您有所幫助:我們的好朋友傳出和傳出耦合。 對於我喜歡他們的東西,我總是混淆他們的定義:

傳入(形容詞):向內或朝某物進行或向某物進行(以循環系統的心臟為例,靜脈將血液返回心臟)。

傳出的(形容詞):從某物向外或遠離某物進行傳導或傳導(以循環系統的心臟為例,動脈將血液從心臟帶走)。

傳入耦合可以通過直接瞭解組件的其他類別,功能或外部過程的數量來衡量。換句話說,此功能有幾個客戶?更重要的是,他們是誰?我們有能力影響他們嗎?如果它們是我可以輕鬆重構的存儲庫中的其他代碼,那麼我可以選擇它們是否以及何時需要更改。如果他們暴露在我所有付費客戶使用的外部Web服務API中,那麼我無法控制他們何時選擇請求更改。相反,傳入的耦合也會受到引入組件的任何更改的影響。我們可以使用API​​版本控制來防止引入破壞性的界面更改(例如,新的強制性輸入),但這不能保護客戶免受故意改正錯誤的錯誤修復或更改實現(例如,緩存或不緩存)的影響。通常,傳入耦合的增加之後,所需測試用例的總數將增加。

傳出耦合可以通過組件知道的其他類,函數或外部進程的數量來衡量,並且您可能會想像,我們只是在發揮另一面作用。 該組件可能會受到其任何依賴項所做的任何更改,並且需要針對一個依賴項與其他依賴項的交互方式來協調所請求或要求的更改。 我們可以使用策略模式和依賴項注入來簡化其中的一些需求,但是無論如何,一旦單個類的依賴項增長到超過四到五個,就很難在心理上合理化其行為。 隨著傳出耦合數量的增加,繼承變化的可能性和頻率也會增加。 通常,傳出耦合的增加之後,將是適當地對組件進行單元測試所需的模擬和設置代碼的數量的增加。

有許多編程語言的工具可以為您評估這些情況。這些耦合中的每一個都有一個更隱蔽的子類型,這種子類型不太容易測量,我將其稱為隱式傳遞耦合。我認為這在靜態類型的語言中可能不太常見,但是一個很好的例子是使用和突變由一個函數創建的鍵-值對字典,並傳遞給第二個以進行後續突變,然後傳遞給第三個消費。儘管無法直接測量,但第一個功能的字典實例化將絕對影響第三個功能的使用它的能力,同樣,第三個功能的需求變化可能會影響到第一個功能的實例化。添加第一個函數的實例化代碼以用於傳遞給多個直接傳入耦合的功能,然後將複雜度增加到可能創建無法減少的錯誤現象實例的程度。

例如,我的團隊正在使用Amazon的DynamoDB緩存一些我們從交易處理期間使用的第三方託管服務中獲取的數據。順便說一句:我仍然發現DynamoDB的API是拜占庭,但實際上我很喜歡使用它。緩存從本質上引入了CAP定理的權衡,但是我們決定接受這種情況下缺乏一致性。為什麼?因為經過與業務和客戶團隊成員的討論,我們瞭解到該數據通常僅在系統配置期間設置,並且一旦交易開始就不會更改,因此認為一個簡單的24小時刷新週期就足夠了。問題解決了……直到我們第一次真正開始設置客戶。我們忘記了配置和測試系統的人員也是利益相關者,他們的週期時間比他們要建立的現實世界要快得多。他們將重用實體,更改映射,解決拼寫錯誤,並循環進行通常一天可能存在幾個月的設置。儘管這些人不是我們系統這些功能的主要利益相關者,但在我們開始滿足實際業務需求之前,他們對配置環境的總體認可是絕對必要的。

如果我們想完全跳過緩存,我們系統中的爆炸半徑是什麼樣的? 只對某些客戶或某些基於請求標頭的交易怎麼辦? 最好的情況是,我們創建緩存接口的新實現,並在factory / build函數中創建一兩個IF語句,以為我們的業務交易組件提供配置。 最壞的情況是,我們將交易處理代碼與直接的DynamoDB調用混為一談,並且我們需要對其中的每一個進行更改,每次都有可能給以前無法正常測試的業務邏輯引入錯誤, 因為緩存命中和丟失幾乎始終是流控制指標。

幾年前,我有一位特別重要的經理和領導者有機會與他合作,如果有人讀過這篇文章,便會確切地知道自己是誰,他試圖向我解釋說,那些為自己的混亂難受的罪魁禍首的軟件開發人員將以失敗告終。天。如今,編寫不安全或明顯破損的代碼的責任通常在公司層面上承擔,即使進行了內部根本原因分析,我也很少看到有人直接參與構建問題來自願解釋他們的參與。確實,這在很大程度上是很有意義的。交付損壞的產品需要一個以上的人,並且往往是多年來的眾多錯誤和缺乏投資的結果,造成了不安全的環境,使這種損壞的產品一開始就成為可能。當單元測試覆蓋率達到50%,不存在針對部署環境的集成測試並且沒有連續交付管道時,您真的可以讓開發人員對引入迴歸負責嗎?

作為當時相對不成熟的開發人員,個人對我的工作負責的想法並不是我所接受的。作為現在不那麼成熟的軟件工程師,我看到了最小化測試覆蓋範圍和緩慢降低系統可靠性的局面,這是需要管理的現實。我將舉一個極端的例子:就像我想象紐約地鐵系統的工程師仍在計劃升級和維護工作的方式一樣,我仍然有義務在風景如畫的技術領域中運用專業知識。這樣做需要在可能不願聽到的人的業務決策結果上顯示一些嚴峻的現實,並且通常最好使用一些易於理解的指標來實現,以幫助傳達好系統與差系統之間的差異。在軟件中,有大量的度量標準,模式和理念試圖表明我們是系統的良好管家,還是我們正在緩慢地紮根針腳以創建一堆難以理解的依賴關係和無數邏輯代碼路徑。

我之前提到的同一位經理不僅宣講了即將到來的遊戲末日,而且還提供了一種有效的解決方法,以應對如此眾多的測量範圍可能引起的分析癱瘓之災。該建議是,在構建系統,服務,子系統,組件,模塊,類或功能時要把握的最重要的概念就是所解決問題的易變性。這不是可以像釐米或公斤那樣普遍測量的東西,但我保證有兩件事:(1)我們將在片刻內完成可測量的項目,(2)您可以輕鬆地發明一個任意系統來比較風險波動性和複雜性(我正在看著您,敏捷的故事要點),只要您瞭解所涉業務的性質。這就是我們的工程師需要在此處開始與我們的業務溝通這些概念的地方領導者瞭解引入某些更改的可能性,然後我們可以運行一些思維模型來適應這些更改。


(本文翻譯自David Jetter的文章《We Programmers should be Engineers》,參考:https://medium.com/swlh/we-programmers-should-be-engineers-e40f774098)


分享到:


相關文章: