拋棄代碼的壞味道 - 提升代碼質(zhì)量之可讀性

[寫在開始]代碼質(zhì)量是每個項目都在呼吁的郊丛。卻是大家都不愿實施的虫给。長期效益誘惑抵抗不了短期收益的現(xiàn)實躯喇。目前辫封,它給予的程序猿只有自我滿足和成就感。一個深陷老舊系統(tǒng)無法脫身程序員面對代碼無奈大家都有耳聞廉丽。在追求交付至上的項目倦微,代碼質(zhì)量問題不是團隊、項目璃诀、公司面臨的問題,只屬于程序猿蔑匣。

代碼質(zhì)量

最近花時間整理:我對代碼的可讀性和可測試性理解。代碼質(zhì)量提升又沒有統(tǒng)一標準裁良,如果尋找不可能完成的任務(wù):說服程序猿修改自己的代碼,一定包含其中价脾。所以,本文純屬個人理解侨把。

這篇文章分為2部分:代碼可讀性和代碼可測試性犀变。

可讀性和可測試是沒有統(tǒng)一的量化標準获枝,尤其是新語言不斷涌現(xiàn)的。

一切量化指標都有綱領(lǐng)性文件骇笔。本文指導性綱領(lǐng):最為我們熟知的是SOLID, KISS, DRY ...。內(nèi)容是他們的具體化笨触。

1、注釋可讀性原則

代碼用來維護和閱讀的"文檔"芦劣,代碼是功能最直接的傳達者。而注釋是為什么要如此傳達的解釋虚吟。開發(fā)模式摒棄注釋本身就不利于代碼可讀性和可維護性源梭。注釋編寫包括如下幾個方面娱俺。

  • 注釋內(nèi)容
    注釋描述為什么code,而不是code是什么废麻。最好描述code是什么的是:代碼實現(xiàn),而不是字面的描述荠卷。而為什么這么做,是代碼無法描述的烛愧。
  • 注釋變化
    保持注釋持續(xù)更新油宜,使之與當前實現(xiàn)匹配。不匹配的注釋非但不是理解code的助推器怜姿,反而是阻燃劑慎冤。
  • 不要添加無意義的注釋
  • 不增加的關(guān)于調(diào)試信息描述
getUTCTime()// debug:獲取UTC 用于記錄耗時
  • 不要無意義的注釋
new Date() // 生成Date 信息

以上反例表明:能用代碼解決的就不要加注釋。

  • 注釋跟蹤
    注釋跟蹤:記錄代碼注釋歷史沧卢。既為了追溯蚁堤,也便于閱讀者和修改方進行信息傳遞。

2但狭、通用可讀性原則

通用原則指對變量披诗、方法、以及類都適用的原則立磁。

  • 格式規(guī)范化
    項目規(guī)范代碼格式化內(nèi)容呈队。諸如 空格縮進、方式修飾符使用唱歧、{}宪摧、if ...else.. 等控制關(guān)鍵字使用、駝峰式命名或者匈牙利命名等颅崩。規(guī)劃化的格式才是代碼可讀性的基礎(chǔ)几于。
  • 命名規(guī)范化
    • 英文使用規(guī)劃化
      比如:修復對應(yīng)的英文, 包括repair fix ...。如何選擇合適的詞匯來描述沿后。盡量使用軟件行業(yè)專用詞匯沿彭,對老舊系統(tǒng)即使無法統(tǒng)一,也不要出現(xiàn)相同術(shù)語而使用不同的詞匯得运。
    • 不要在命名中嵌入數(shù)據(jù)類型尤其是函數(shù)中
//功能是把日期轉(zhuǎn)換成Int膝蜈,這是不建議的方式锅移,*函數(shù)的返回類型*標識的Int
//函數(shù)中加入類型是畫蛇添足
.... //偽代碼
  getDate2Int() 
  • 使用好的框架
    避免重復造輪子熔掺,使用好的框架。在每個領(lǐng)域都有優(yōu)秀的開源框架非剃。如數(shù)據(jù)庫連接池管理庫Druid HikariCP DBCP...置逻,線程池管理框架、支持緩存的Redis备绽,CacheMem券坞。優(yōu)秀的框架即戰(zhàn)力很強大鬓催,我們都值得擁有。

  • 避免重復的代碼
    堅持DRY(don't repeat yourself.)原則一百年不動搖恨锚。

  • 代碼模塊化
    模塊化沒有直接受益,我只能說對可讀性而言太重要猴伶。
    模塊化和組件化設(shè)計意味著最小知識、技能和依賴在系統(tǒng)中筝尾,防止教條出現(xiàn)、構(gòu)建抽象層筹淫、避免設(shè)計復雜的相互依賴呢撞、功能獨立性等....

  • 代碼review原則

讓review真正運作起來。review代碼是檢驗可讀性最佳標準薛匪。review過程中的逸尖,信息溝通和經(jīng)驗傳遞是提升編碼水平和形成習慣的最佳途徑瘸右。

  • 給代碼以時間

套用大劉的這句話。試想幾個月后甚至更久后苞俘,我們回看代碼龄章,若邏輯不清晰、結(jié)構(gòu)待調(diào)整岗憋,說明代碼可讀性有提升空間锚贱。如果你意識到代碼可讀性差,也表明個人能力提升晋修。所以一切交給時間吧凰盔。

3、函數(shù)可讀性原則

  • 函數(shù)簡短化
    受過長函數(shù)苦的趴拧,就不要讓其它人繼續(xù)受累山叮。我們不武斷提倡每個函數(shù)少于5行,但絕不讓它們超過 50行脑又。
  • 參數(shù)列表簡短化
    限制參數(shù)的長度锐借, 3~5個為宜。過長的參數(shù)列表严卖,往往意味這超長的函數(shù)和復雜代碼邏輯哮笆。
  • 參數(shù)最小化原則
    遵守參數(shù)最小化原則汰扭,即不需要的參數(shù)不用傳入。參數(shù)沒有最小化项阴,是代碼腐化的主要原因笆包。
calss Person(name: String, addr: String, age: Int, sex: String)
def isFemale(person: Person): Boolean = {
    ....
}

上例中判斷是否是性別歉胶,只用傳入sex就滿足功能要求跨扮,傳入的參數(shù)是Person 違背參數(shù)最小化原則验毡。

  • 代碼執(zhí)行邏輯統(tǒng)一
    我們功能實現(xiàn)時,過程控制條件太多晶通,且沒有統(tǒng)一邏輯。代碼經(jīng)骋灰玻看到if ...else...滿天飛椰苟,但細讀下來各個分支邏輯并不同树叽。如下正例:都是根據(jù)小時條件生成結(jié)果。反例則可讀性不高洁仗。
{
   DateTime time = DateTime.Now;
   if (time.Hour >= 0 && time.Hour < 6)
   {
       return "Night";
   }
   if (time.Hour >= 6 && time.Hour < 12)
   {
       return "Morning";
   }
  ....
   return "Evening";
}
//反例性锭,lineitem card并不是一個維度內(nèi)容
if (lineItem != null && (lineItem.quantity > 0 && customer.isActive() && (card.expirityYear > 2010 || card.type == AMX)) || couponCode.isValid()) {
// details..
}
//封面圖是又一可讀性反證
  • 代碼有效性
    義無反顧的刪除過期代碼和調(diào)試代碼草冈。減少無用日志輸出。讓代碼有意義

  • 單一職責
    就是我們常說的SRP方淤。就函數(shù)而言蹄殃,保證以上原則SRP就滿足了。

3讳苦、類可讀性原則

  • 數(shù)據(jù)類和實現(xiàn)類分離
    數(shù)據(jù)的提供者和使用者分離鸳谜。避免類中存儲數(shù)據(jù)式廷,外部數(shù)據(jù)在類生成時傳入,類只負責對數(shù)據(jù)的操作蝗肪。

  • 不同類提供不同接口
    如果內(nèi)部相似的類,對外卻提供不同的接口辛馆,讓其接口統(tǒng)一:創(chuàng)建接口層豁延,etc.保持內(nèi)外提供相同接口。

  • 簡化初始化邏輯
    面向?qū)ο缶幊烫桑嘀乩^承讓類初始化邏輯異常復雜袋狞。為了簡化邏輯,類初始化邏輯耦合盡量小法焰。

  • 減少類接口暴露數(shù)量
    是時候使用訪問級別修飾符限定訪問權(quán)限埃仪,和簡化對外接口陕赃。

  • 明確函數(shù)歸屬原則
    若函數(shù)實現(xiàn)依賴其它類,那么它屬于依賴函數(shù)傻丝,而不是當前類诉儒。

  • 隔離依賴
    常見場景:依賴庫如無法進行修改,為了將來便于使用新依賴庫泛释,構(gòu)造接口類進行隔離温算。防止對舊有庫的行為使用。

  • 廢棄任何不必須類
    任何類都會增加項目的復雜度茄茁,多余功能類進行廢棄和合并

  • 重構(gòu)類
    如果一個類修改,同時要修改若干其它類付燥,對該類進行進行重構(gòu)锦庸。保證修改僅限在一個類中甘萧。新需求引入穩(wěn)定系統(tǒng)梆掸,可行性方案越少,越利于維護怪得。系統(tǒng)腐化的風險越小卑硫。

后續(xù)

代碼可讀性個人性很強。不同的階段入挣,對美的理解不同径筏。就如同欣賞NBA比賽障陶,時間久了,馬刺黑恢氯,也會成為刺蜜鼓寺。品味是個很玄幻的東西,要個人努力和時間積累指黎。

一切的提升源于認識深入州丹。

喜歡就冒個泡或賞個贊哈
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吓揪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柠辞,老刑警劉巖叭首,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焙格,死亡現(xiàn)場離奇詭異,居然都是意外死亡眷唉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門蛤虐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笆焰,“玉大人,你說我怎么就攤上這事嚷掠≤衤浚” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵霹娄,是天一觀的道長犬耻。 經(jīng)常有香客問我,道長枕磁,這世上最難降的妖魔是什么计济? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮学密,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘腻暮。我一直安慰自己毯侦,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布款青。 她就那樣靜靜地躺著霍狰,像睡著了一般饰及。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宾濒,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天绘梦,我揣著相機與錄音赴魁,去河邊找鬼。 笑死榄棵,一個胖子當著我的面吹牛潘拱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瘪弓,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼杠茬,長吁一口氣:“原來是場噩夢啊……” “哼月褥!你這毒婦竟也來了宁赤?” 一聲冷哼從身側(cè)響起栓票,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎佛猛,沒想到半個月后继找,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逃沿,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年边臼,在試婚紗的時候發(fā)現(xiàn)自己被綠了假消。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡臼予,死狀恐怖啃沪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情半哟,我是刑警寧澤签餐,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布氯檐,位于F島的核電站,受9級特大地震影響糯崎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沃呢,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望某抓。 院中可真熱鬧否副,春花似錦崎坊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚕捉。三九已至,卻和暖如春秘通,著一層夾襖步出監(jiān)牢的瞬間敛熬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工话原, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诲锹,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓黄虱,卻偏偏與公主長得像捻浦,于是被迫代替她去往敵國和親晤揣。 傳聞我的和親對象是個殘疾皇子昧识,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容