代碼壞味道:不合理命名與重復(fù)代碼

一. 命名

1.1 命名是否具有業(yè)務(wù)含義

(1) 命名不精準(zhǔn),用詞寬泛淀歇,不能有效反應(yīng)代碼含義

從溝通的角度看,這就不是一個(gè)有效的溝通姚糊。要想理解它想虎,需要消耗大量的認(rèn)知成本,時(shí)間和精力,同樣也增加了后來(lái)人包括我們自己維護(hù)代碼的成本叛拷。

其中,Info岂却、data忿薇、flag、process躏哩、handler署浩、build、maintain扫尺、manager筋栋、modify等,都是屬于典型的過(guò)于寬泛的名字正驻,當(dāng)這些名字出現(xiàn)的地方弊攘,多半都是寫代碼的人當(dāng)時(shí)沒有想好用什么名字。

命名要能夠描述出這段代碼在做的事情姑曙,好的名字應(yīng)該描述意圖襟交,而非細(xì)節(jié)。

命名演化示例:

processChapter:處理章節(jié)伤靠,命名寬泛
changeChapterToTranlsating:將章節(jié)修改為翻譯中  在描述細(xì)節(jié)
startTranslation:開始翻譯捣域,描述意圖
(2) 用技術(shù)術(shù)語(yǔ)命名
xxxList,xxxMap宴合,xxxSet

這是一種不費(fèi)腦子的命名方式焕梅,因?yàn)樗且环N基于實(shí)現(xiàn)細(xì)節(jié)的命名方式。
重要原則:面向接口編程卦洽,不要面向?qū)崿F(xiàn)編程贞言。因?yàn)榻涌谑欠€(wěn)定的阀蒂,而實(shí)現(xiàn)是易變的蜗字。

正確示例:

bookList -> books
xxxMap -> xxxMaping

實(shí)際上,在實(shí)際的代碼中脂新,技術(shù)術(shù)語(yǔ)的出現(xiàn)挪捕,往往代表著缺少了一個(gè)應(yīng)有的模型。

比如在業(yè)務(wù)代碼中直接出現(xiàn)了redis争便,通常來(lái)說(shuō)级零,我們真正需要的只是一個(gè)緩存,而redis只是緩存這個(gè)模型的一個(gè)實(shí)現(xiàn)而已。

而再進(jìn)一步奏纪,緩存這個(gè)概念也是一種技術(shù)術(shù)語(yǔ)鉴嗤,從某種意義上,它也不應(yīng)該出現(xiàn)在業(yè)務(wù)代碼中序调。Spring就做的比較好醉锅,需要緩存,就加上@Cacheable的注解发绢。

注意硬耍,在技術(shù)類項(xiàng)目中,存在技術(shù)術(shù)語(yǔ)即是業(yè)務(wù)語(yǔ)言的情況边酒;但對(duì)于業(yè)務(wù)項(xiàng)目经柴,這個(gè)說(shuō)法就必須重新審視。

(3) 用業(yè)務(wù)語(yǔ)音寫代碼

編寫可維護(hù)的代碼墩朦,要使用業(yè)務(wù)語(yǔ)音坯认,而怎么知道自己的命名是否用的是業(yè)務(wù)語(yǔ)音呢,就是把這個(gè)詞講給產(chǎn)品經(jīng)理氓涣,看他是否知道牛哺。

一個(gè)好的做法:在團(tuán)隊(duì)建立自己的業(yè)務(wù)語(yǔ)言詞匯表。

approveChapter(long chapterId劳吠,long userId)
-> approveChapter(long chapterId荆隘,long reviewerId)
(4) 小結(jié)
  • 壞味道:不精準(zhǔn)的命名,用技術(shù)術(shù)語(yǔ)命名赴背。
  • 解決之道:好的命名要體現(xiàn)代碼在做什么椰拒,但無(wú)需展示代碼的細(xì)節(jié),更進(jìn)一步凰荚,要準(zhǔn)確體現(xiàn)意圖燃观,而不是實(shí)現(xiàn)細(xì)節(jié),更高的要求是便瑟,用業(yè)務(wù)語(yǔ)言寫代碼缆毁。
  • 原則:描述意圖,而非細(xì)節(jié)到涂;面向接口編程脊框,接口是穩(wěn)定的,實(shí)現(xiàn)是易變的践啄;命名出現(xiàn)技術(shù)名詞浇雹,往往是缺少了一個(gè)模型;使用業(yè)務(wù)語(yǔ)音屿讽。

1.2 命名是否符合英語(yǔ)語(yǔ)法

(1)違反語(yǔ)法規(guī)則命名

完成翻譯昭灵,方法名:completedTranslate 不是有效的動(dòng)賓結(jié)構(gòu) ->completeTranslation
重新翻譯,方法名:retranslation 應(yīng)該是一個(gè)動(dòng)詞 -> retranslate

常見的命名規(guī)則:類名是一個(gè)名詞,表示一個(gè)對(duì)象烂完;方法名是一個(gè)動(dòng)詞试疙,或是動(dòng)賓短語(yǔ),表示一個(gè)動(dòng)作抠蚣。

(2)不準(zhǔn)確的英語(yǔ)詞匯
審核:
audit:更官方祝旷,偏向?qū)徲?jì)
review

常用的做法就是把中文詞扔到字典網(wǎng)站從返回的眾多結(jié)果中找到一個(gè)自己看著順眼的。好一點(diǎn)的做法是根據(jù)google翻譯嘶窄,然后根據(jù)二者的英文釋義進(jìn)行比較怀跛。

其實(shí),在這種情況下护侮,最好的解決方案就是建立一個(gè)業(yè)務(wù)詞匯表,而不是自己臆想储耐。建立詞匯表的一個(gè)關(guān)鍵點(diǎn)是用集體智慧羊初,而非個(gè)體智慧。另外什湘,業(yè)務(wù)詞匯表也是屬于構(gòu)建團(tuán)隊(duì)同樣語(yǔ)言的一部分成果长赞。

(3)英語(yǔ)單詞拼寫錯(cuò)誤

一個(gè)好的解決方案,借助工具插件檢查拼寫錯(cuò)誤闽撤。

(4)小結(jié)
  • 壞味道:命名違反語(yǔ)法規(guī)則得哆,用詞不準(zhǔn)確,單詞拼寫錯(cuò)誤哟旗。更低級(jí)的一些贩据,使用拼音,使用不恰當(dāng)?shù)膯卧~簡(jiǎn)寫闸餐。(如果非要用縮寫饱亮,可以用一些行業(yè)通用的縮寫,而最好不要自己創(chuàng)造舍沙,前提是一定要約定好)
  • 解決之道:制定代碼規(guī)范近上,比如類名用名詞,函數(shù)名用動(dòng)詞或動(dòng)賓短語(yǔ)拂铡;建立團(tuán)隊(duì)詞匯表壹无;經(jīng)常進(jìn)行代碼評(píng)審。
    -小工具:命名插件codelf感帅。

二. 重復(fù)代碼

重復(fù)代碼產(chǎn)生的一些常見原因:

  • 代碼結(jié)構(gòu)不合理導(dǎo)致同一個(gè)實(shí)現(xiàn)散落各處斗锭。由于初期代碼結(jié)構(gòu)設(shè)計(jì)不合理導(dǎo)致后續(xù)功能實(shí)現(xiàn)無(wú)法快速找到已有實(shí)現(xiàn),或者找到了但是不好引用已有實(shí)現(xiàn)失球。改進(jìn):初期設(shè)計(jì)代碼邏輯合理拒迅,對(duì)于不合理的地方要及時(shí)重構(gòu) 防止演變成原因2。
  • 為了穩(wěn)定性,不動(dòng)老邏輯璧微,拷貝一份作箍。由于對(duì)于業(yè)務(wù)的不熟悉和對(duì)自己代碼能力的不信任,不敢重構(gòu)導(dǎo)致前硫。改進(jìn):通過(guò)微重構(gòu)進(jìn)行多次迭代小改進(jìn)慢慢優(yōu)化胞得。
  • 寫的時(shí)候?yàn)榱丝欤捎跁r(shí)間緊張或者能力問題屹电,無(wú)法識(shí)別出的壞代碼阶剑。改進(jìn):提升能力。
(1) 復(fù)制粘貼的代碼
(2) 結(jié)構(gòu)重復(fù)的代碼

示例如下:

@Task
public void sendBook() {
    try {
        this.service.sendBook();
    } catch (Throwable t) {
        this.notification.send(new SendFailure(t)));
        throw t;
    }
}

@Task
public void sendChapter() {
    try {
        this.service.sendChapter();
    } catch (Throwable t) {
        this.notification.send(new SendFailure(t)));
        throw t;
    }
}

優(yōu)化之后:

@Task
public void sendChapter() {
    executeTask(this.service::sendChapter);
}

@Task
public void sendBook() {
    executeTask(this.service::sendBook);
}

private void executeTask(final Runnable runnable) {
    try {
        runnable.run();
    } catch (Throwable t) {
        this.notification.send(new SendFailure(t)));
        throw t;
    }
}

對(duì)于支持函數(shù)式編程的程序設(shè)計(jì)語(yǔ)言來(lái)說(shuō)危号,可以用語(yǔ)言提供的便利寫法簡(jiǎn)化代碼的編寫牧愁,就像上面的代碼就是用了 Java 里的方法引用(Method Reference)

(3) if 和 else 代碼塊中的語(yǔ)句高度類似

只要你看到 if 語(yǔ)句出現(xiàn)外莲,而且 if 和 else 的代碼塊長(zhǎng)得又比較像猪半,多半就是出現(xiàn)了這個(gè)壞味道。

if (user.isEditor()) {
    service.editChapter(chapterId, title, content, true);
} else {
    service.editChapter(chapterId, title, content, false);
}

優(yōu)化之后:

service.editChapter(chapterId, title, content, user.isEditor());
(4) 小結(jié)
  • 壞味道:重復(fù)的代碼偷线,重復(fù)的結(jié)構(gòu)磨确,if 和 else 代碼塊中的語(yǔ)句高度類似
  • 解決之道:不要使用復(fù)制粘貼;先提取函數(shù)声邦,然后在需要的地方調(diào)用這個(gè)函數(shù)乏奥。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市亥曹,隨后出現(xiàn)的幾起案子邓了,更是在濱河造成了極大的恐慌,老刑警劉巖媳瞪,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驶悟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡材失,警方通過(guò)查閱死者的電腦和手機(jī)痕鳍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)龙巨,“玉大人笼呆,你說(shuō)我怎么就攤上這事≈急穑” “怎么了诗赌?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)秸弛。 經(jīng)常有香客問我铭若,道長(zhǎng)洪碳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任叼屠,我火速辦了婚禮瞳腌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘镜雨。我一直安慰自己嫂侍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布荚坞。 她就那樣靜靜地躺著挑宠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颓影。 梳的紋絲不亂的頭發(fā)上各淀,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音诡挂,去河邊找鬼碎浇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛咆畏,可吹牛的內(nèi)容都是我干的南捂。 我是一名探鬼主播吴裤,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼旧找,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了麦牺?” 一聲冷哼從身側(cè)響起钮蛛,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剖膳,沒想到半個(gè)月后魏颓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吱晒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年甸饱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仑濒。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叹话,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出墩瞳,到底是詐尸還是另有隱情驼壶,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布喉酌,位于F島的核電站热凹,受9級(jí)特大地震影響泵喘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜般妙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一纪铺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧股冗,春花似錦霹陡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至怯疤,卻和暖如春浆洗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背集峦。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工伏社, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人塔淤。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓摘昌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親高蜂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子聪黎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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