一. 定名
1.1 定名是否具有业务寄义
(1) 定名不精准,用词宽泛,不能有用反应代码寄义
从沟通的角度看,这就不是一个有用的沟通。要想明白它,必要斲丧大量的认知本钱,时间和精神,同样也增长了厥后人包罗我们本身维护代码的本钱。
此中,Info、data、flag、process、handler、build、maintain、manager、modify等,都是属于典范的过于宽泛的名字,当这些名字出现的地方,多半都是写代码的人其时没有想好用什么名字。
定名要可以大概形貌出这段代码在做的事变,好的名字应该形貌意图,而非细节。
定名演化示例:
processChapter:处置惩罚章节,定名宽泛changeChapterToTranlsating:将章节修改为翻译中 在形貌细节startTranslation:开始翻译,形貌意图(2) 用技能术语定名
xxxList,xxxMap,xxxSet这是一种不费脑筋的定名方式,由于它是一种基于实现细节的定名方式。
紧张原则:面向接口编程,不要面向实现编程。由于接口是稳固的,而实现是易变的。
准确示例:
bookList -> booksxxxMap -> 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) 布局重复的代码
示比方下:
@Taskpublic void sendBook() { try { this.service.sendBook(); } catch (Throwable t) { this.notification.send(new SendFailure(t))); throw t; }}@Taskpublic void sendChapter() { try { this.service.sendChapter(); } catch (Throwable t) { this.notification.send(new SendFailure(t))); throw t; }}优化之后:
@Taskpublic void sendChapter() { executeTask(this.service::sendChapter);}@Taskpublic 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 代码块中的语句高度类似
- 办理之道:不要使用复制粘贴;先提取函数,然后在必要的地方调用这个函数。
|