代码坏味道:不合理命名与重复代码

一. 命名

1.1 命名是否具有业务含义

(1) 命名不精准,用词宽泛,不能有效反应代码含义

从沟通的角度看,这就不是一个有效的沟通。要想理解它,需要消耗大量的认知成本,时间和精力,同样也增加了后来人包括我们自己维护代码的成本。

其中,Info、data、flag、process、handler、build、maintain、manager、modify等,都是属于典型的过于宽泛的名字,当这些名字出现的地方,多半都是写代码的人当时没有想好用什么名字。

命名要能够描述出这段代码在做的事情,好的名字应该描述意图,而非细节。

命名演化示例:

processChapter:处理章节,命名宽泛
changeChapterToTranlsating:将章节修改为翻译中  在描述细节
startTranslation:开始翻译,描述意图
(2) 用技术术语命名
xxxList,xxxMap,xxxSet

这是一种不费脑子的命名方式,因为它是一种基于实现细节的命名方式。
重要原则:面向接口编程,不要面向实现编程。因为接口是稳定的,而实现是易变的。

正确示例:

bookList -> books
xxxMap -> xxxMaping

实际上,在实际的代码中,技术术语的出现,往往代表着缺少了一个应有的模型。

比如在业务代码中直接出现了redis,通常来说,我们真正需要的只是一个缓存,而redis只是缓存这个模型的一个实现而已。

而再进一步,缓存这个概念也是一种技术术语,从某种意义上,它也不应该出现在业务代码中。Spring就做的比较好,需要缓存,就加上@Cacheable的注解。

注意,在技术类项目中,存在技术术语即是业务语言的情况;但对于业务项目,这个说法就必须重新审视。

(3) 用业务语音写代码

编写可维护的代码,要使用业务语音,而怎么知道自己的命名是否用的是业务语音呢,就是把这个词讲给产品经理,看他是否知道。

一个好的做法:在团队建立自己的业务语言词汇表。

approveChapter(long chapterId,long userId)
-> approveChapter(long chapterId,long reviewerId)
(4) 小结
  • 坏味道:不精准的命名,用技术术语命名。
  • 解决之道:好的命名要体现代码在做什么,但无需展示代码的细节,更进一步,要准确体现意图,而不是实现细节,更高的要求是,用业务语言写代码。
  • 原则:描述意图,而非细节;面向接口编程,接口是稳定的,实现是易变的;命名出现技术名词,往往是缺少了一个模型;使用业务语音。

1.2 命名是否符合英语语法

(1)违反语法规则命名

完成翻译,方法名:completedTranslate 不是有效的动宾结构 ->completeTranslation
重新翻译,方法名:retranslation 应该是一个动词 -> retranslate

常见的命名规则:类名是一个名词,表示一个对象;方法名是一个动词,或是动宾短语,表示一个动作。

(2)不准确的英语词汇
审核:
audit:更官方,偏向审计
review

常用的做法就是把中文词扔到字典网站从返回的众多结果中找到一个自己看着顺眼的。好一点的做法是根据google翻译,然后根据二者的英文释义进行比较。

其实,在这种情况下,最好的解决方案就是建立一个业务词汇表,而不是自己臆想。建立词汇表的一个关键点是用集体智慧,而非个体智慧。另外,业务词汇表也是属于构建团队同样语言的一部分成果。

(3)英语单词拼写错误

一个好的解决方案,借助工具插件检查拼写错误。

(4)小结
  • 坏味道:命名违反语法规则,用词不准确,单词拼写错误。更低级的一些,使用拼音,使用不恰当的单词简写。(如果非要用缩写,可以用一些行业通用的缩写,而最好不要自己创造,前提是一定要约定好)
  • 解决之道:制定代码规范,比如类名用名词,函数名用动词或动宾短语;建立团队词汇表;经常进行代码评审。
    -小工具:命名插件codelf。

二. 重复代码

重复代码产生的一些常见原因:

  • 代码结构不合理导致同一个实现散落各处。由于初期代码结构设计不合理导致后续功能实现无法快速找到已有实现,或者找到了但是不好引用已有实现。改进:初期设计代码逻辑合理,对于不合理的地方要及时重构 防止演变成原因2。
  • 为了稳定性,不动老逻辑,拷贝一份。由于对于业务的不熟悉和对自己代码能力的不信任,不敢重构导致。改进:通过微重构进行多次迭代小改进慢慢优化。
  • 写的时候为了快,由于时间紧张或者能力问题,无法识别出的坏代码。改进:提升能力。
(1) 复制粘贴的代码
(2) 结构重复的代码

示例如下:

@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;
    }
}

优化之后:

@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;
    }
}

对于支持函数式编程的程序设计语言来说,可以用语言提供的便利写法简化代码的编写,就像上面的代码就是用了 Java 里的方法引用(Method Reference)

(3) if 和 else 代码块中的语句高度类似

只要你看到 if 语句出现,而且 if 和 else 的代码块长得又比较像,多半就是出现了这个坏味道。

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

优化之后:

service.editChapter(chapterId, title, content, user.isEditor());
(4) 小结
  • 坏味道:重复的代码,重复的结构,if 和 else 代码块中的语句高度类似
  • 解决之道:不要使用复制粘贴;先提取函数,然后在需要的地方调用这个函数。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容