什麼才是好代碼?
「什麼狗屁代碼,老子看了幾個小時也沒明白!」
「這麼爛的代碼,到底是誰寫的!」
Bob大叔說:「衡量代碼質量的唯一標準是閱讀該代碼時說髒話的次數」, 真是很有趣的說法。
什麼是好的代碼? 這個問題可能是仁者見仁,智者見智。 我先說說我的看法,歡迎大家留言討論。
我個人覺得好代碼分為兩個層面, 一個是道,一個術。
1
好代碼之「道」
「道」這裡指的設計,是對問題本質的洞察,是良好的抽象。
對一個好的系統設計來說,我覺得有這麼一個重要的特點: 系統由幾個基本的概念組成,這幾個概念體現了系統的本質,形成了系統的骨架,他們非常地穩定,生命周期很長。
系統的其他代碼圍繞著這幾個基本概念生長,變化,擴展,不斷地演進。
舉個例子, Linus 把Git的數據結構設計得非常精良,據說在之後十年的開發中,feature 擴展了無數,基礎數據結構卻很少變動。
我相信Linus在開發第一版Git的時候,肯定對它要解決的問題--分散式源碼配置管理--有著深刻的洞察,實際上Linux內核的開發就是一個典型的、分散式的架構和流程, Linus要做的就是創建一個匹配這個流程的工具,基於對問題的深刻理解,他設計出了Git的系統骨架。
正所謂「簡約而不簡單」。
但是「道」這個東西太虛無縹緲了,有沒有一些可以真正指導我們做設計的準則?
在面向對象編程的領域,這個道就是面向對象的設計原則,Robert Mafrtin在《敏捷軟體開發 原則、模式與實踐》中總結了SOLID原則。
Single responsibility principle : 單一職責原則
Open/closed principle :開閉原則
Liskov substitution principle :Liskov替換原則
Interface segregation principle :介面隔離原則
Dependency inversion principle : 依賴反轉原則
如果我們設計出的類能滿足這些原則,就不會有僵化、脆弱、重複、晦澀等種種可以導致代碼腐化的問題。代碼就容易擴展,生命力就會長久。
但是這些核心的、優美的設計很有可能在進度的壓力下出問題:做個簡單粗暴的修改,就能省好幾天功夫,不用晚上加班了, 很少人能經受這樣的巨大誘惑。 所以要堅決守住這些核心的設計,防止腐化。
如果你做的是基礎組件的開發,為別人提供服務和API,那必須在設計層面狠下功夫才行,因為API的每次變化都會極大地影響上層應用。
很多人使用Spring做業務軟體開發,使用的無非就是Controller, Service, DAO這樣已經劃分好的結構,增刪改查就搞定了,似乎感受不到設計帶來的力量。 但我相信,系統中或多或少隱藏著幾個核心的數據結構,你只是沒有注意到而已。
如果業務很複雜,不要讓他們分散在系統的各個地方,要對他們做抽象,形成一套可以獨立的,不依賴框架的,生命力長久的業務模型。
2
術:寫代碼的十八般武器
術就是編寫代碼時的具體技巧和最佳實踐。
這些技巧和實踐在很多書中都有描述,比如《Effective Java》中提到的很多:
使可變性最小化
介面優於抽象類
優先考慮泛型
通過介面引用對象
遵守普遍接受的命名慣例
......
再比如《編寫可讀代碼的藝術》和《代碼簡潔之道中》總結的技巧:
避免if嵌套的層次過深,形成「金字塔」代碼
局部變數申明儘可能靠近使用的地方
如有可能,儘可能用常量
減少控制流變數
拆分超長表達式
函數應該短小,只做一件事情
把過多的參數封裝成類
......
把這些「術」應用到編程當中,會讓代碼更加的專業。
很明顯,這些技巧和實踐比較容易學習,程序員學會了一門語言以後,應該去掌握它們,讓自己的代碼變得簡潔可讀。
相對於「術」,「悟道」就難得多,洞察問題本質,做出良好抽象,遵循設計原則,這都是內功,都需要不斷修鍊。
但是這些「道」直接決定了系統的未來方向,設計得不好,再多的「術」也於事無補。
來源:碼農翻身
TAG:ServiceHot |