5 種使您的軟體不可維護的 C# 常見錯誤 - 由 Derek Comartin 解釋
[[academy-video-youtube({"vid": "G9FOfcVQNg4", "start_time": "0", "title": "5 Mistakes That Make Your Code Unmaintainable", "creator": "Derek Comartin", "length": "13m 46s"})]]
撰寫乾淨、可維護且高效的程式碼是專業C#開發者的標誌。 然而,許多C#編程語言的常見錯誤會隨著時間的推移使程式碼庫成為一場噩夢。在本文中,我們將總結Derek Comartin的影片《5個讓程式碼難以維護的錯誤》中的見解,探討這些錯誤。
Derek分享了他在構建大型業務系統時的見解,並指出開發者-尤其是在C#中-經常犯下的五個主要軟體設計錯誤。 讓我們深入研究這些問題,並以Derek的影片為指南。
1. 缺乏對狀態的擁有權
Derek首先指出允許多個邊界或服務在沒有明確擁有權的情況下更新共享資料是一個錯誤。他以一個例子說明,計費系統進入應用程式的另一部分並改變狀態。 這導致資料的一致性問題,特別是當該物件駐留在系統內的不同位置時。
這種自由方式造成的錯誤使開發者會問:"為什麼這個資料不正確?"或"誰改變了它?"Derek強調您必須定義擁有權。系統的每一部分都應該公開一個明確定義的API或方法-負責管理狀態。
Derek建議建立明確的命令和查詢,而不是允許應用程式的任何部分修改共享資料。 例如,當您想更新一個貨件時,通過專用介面發布命令。 這提供了結構,避免了無法追蹤的變更導致的資源洩漏。
2. 隱式程式碼與顯式工作流程
根據Derek的說法,許多系統高度依賴于CRUD操作(建立、讀取、更新、刪除),但這會導致隱式工作流程。 程式碼在技術上是功能性的,但缺乏對其執行內容的清晰理解。 如果您的類僅支持通用操作,實際的業務工作流程就會被隱藏。
看看以下範例:司機取件並生成提單。 如果系統只執行UpdateShipment操作,很難明確這個字串改變(如BOL號碼)是取件還是修正所致。 Derek指出,我們應該用PickupStopLoaded這類顯式操作替換模糊的更新。
這有助於提高程式碼的可讀性。 這也有助於異常處理解,因為當發生異常ex時,堆棧跟踪將清楚顯示哪個操作失敗。 顯式方法還支持更好的編碼標準,因為每個功能都有單一職責。
3. 增加無用的間接性
Derek接著討論了間接性-即在您的呼叫者與目標方法之間插入不必要的層。 他以資料庫連接為例說明這一點。 控制器可能調用一個服務,該服務調用一個助手,再調用另一個服務,最終通過Entity Framework執行查詢。
這種抽象的金字塔結構使問題追踪和性能改進變得更加困難。 雖然建立抽象層可以提供幫助,例如包裝IDisposable介面以更好地進行資源管理,但Derek警告不要過度實施。 您應該問自己,您的抽象是否簡化了API,或僅僅隱藏了一個僅存在於一個地方的第三方依賴。
與其為了分層而分層,Derek建議直接管理耦合。 過多的間接性不僅使程式碼雜訊增加,也增加了記憶體洩漏的可能性,削弱了垃圾收集收益。
4. 玩"如果……會怎樣"的遊戲
Derek指出的下一個錯誤是為可能永遠不會發生的假設情況做準備-他稱之為"如果……會怎樣"遊戲。許多C#開發者編寫靈活的類和函式,以適應未來的需求。 例如:"如果我們需要支持兩種語言怎麼辦?"或"如果我們需要更換技術怎麼辦?"
Derek警告說,這種心態會導致臃腫的框架和過於通用的程式碼。 他提到曾遭遇字串連接邏輯和參考型別包裝器,沒人了解其功能,因為它們只為一個真正的使用案例服務。
與其為未知做準備,Derek建議專注於實際需求。 每個方法和變數都應當有當前且合理的目的。 未使用的功能只會增加維護成本。正如Derek所說,這不僅僅是開發時間的問題-還是擁有成本。如果您的公共布林Equals實現涵蓋了您能想到的每個邊界,但實際上卻沒有發生過-您已經浪費了寶貴的時間。
5. 沒有正確管理工作流程
最後,Derek討論了將工作流程視為程式塊而不是模組化步驟的錯誤。 他使用了一個真實世界的例子:在線下訂單。使用者完成結帳後,系統會扣款,然後發送確認電子郵件。
如果有一步失敗-例如付款流程-您的程式碼如何反應? 您會回滾訂單嗎? 顯示錯誤嗎? 發送失敗的電子郵件嗎? Derek解釋說,將這些集中在一個塊中會造成無法管理的複雜性。
他建議將工作流程設計為小而獨立的單元,通過訊息進行溝通。 使用非同步Task操作和yield return可以讓這些步驟更易於管理。 此外,通過外部資源(如文件存取或資料庫連接)周圍使用using語句和using塊可以幫助防止記憶體洩漏。
例如,圍繞流的using塊可確保其正確釋放-這在處理IDisposable介面時至關重要。 當工作流程變得復雜時,這些最佳實踐確保例外能夠有效地捕獲和處理,保持性能和可維護性。
總結:撰寫乾淨、可維護的程式碼
正如Derek在他的影片中於12:45得出的結論,他不僅僅是將這些錯誤視為他所見過的,也視為他在構建大型業務系統時自己犯過的錯誤。 這些是從經驗中汲取的教訓,他鼓勵觀眾在評論中分享自己的錯誤。
Derek的建議不僅適用於C#,也適用於許多其他語言。 無論您是在進行字串比較、Equals()方法,還是設計新功能,關鍵在於清晰、意圖,並保持程式碼的可維護性。
如果您有興趣提升您的C#技能並避免這些常見錯誤,Derek的頻道提供了許多關於系統架構、設計模式和現實世界的編程語言建議的免費資源。避免這些錯誤中的任何一個都能大大提升您的專案質量。
所以,下次當您開始撰寫程式碼時,記住Derek的話,問問自己:"這是否比需要的更複雜?"
如需更多類似內容,請查看Derek Martin的CodeOpinion YouTube頻道。


