【代码精进】| 总结/Edison Zhou


作为一个后端工程师,想必在职业生涯中都写过一些不好维护的代码。本文是我学习《代码之丑》的学习总结,今天第一天发车,先来看看在命名上的一些常犯的坏味道。

0为何要品代码坏味道

Martin Flower在《重构》一书中给不好维护的这一类代码取了一个艺名:代码的坏味道,而这些坏味道一旦堆积多了,整个系统虽然还是可以平稳运行,但是就是让程序员不敢动,更别提重构了。

因为......

哎,都是打工人,谁容易啊?

1不精准的命名

直接来看一段坏味道代码:

public void ProcessChapter(long chapterId)
{Chapter chapter = _repository.GetChapterById(chapterId);if (chapter == null){throw new ArgumentException($"Unknown chapter [{chapterId}]");}chatper.TransactionState == TransactionState.TRANSLATING;_repository.UpdateChapter(chapter);
}

此段代码存在的问题:方法名ProcessChapter命名过于宽泛,不能精准描述意图,是代码难以理解的根源所在

同类型的词汇请各位看官自查,例如:data,info,flag,process,handle,build,maintain,manage,modify等等等,它们应该都出现在你我的项目代码中过。

重构方法:命名需要能够描述出这段代码在做的事情,根据代码的逻辑含义,调整其命名为 ChangeChapterToTranslating,是不是无论谁来接手这个方法的代码就都好理解了?

public void ChangeChapterToTranslating(long chapterId)
{......
}

一个好的名字应该是描述意图,而非细节的。那么,我们再重构一下,结合具体的业务,将其命名改为 StartTranslation,即开始翻译,是不是就更能体现业务含义了?

public void StartTranslation(long chapterId)
{......
}

2用技术术语命名

这是一个我也经常犯的坏味道:

List<Book> bookList = service.GetBooks();

这个bookList的原因是因为它的类型是List,还有xxxDict,xxxMap等,它不费脑子,但它却只是一种基于实现细节的命名方式。

重构方法:使用面向意图的名字

List<Book> books = service.GetBooks();

又如,如果在业务代码中出现了Redis这类的中间件:

public Book GetByIsbn(string isbn)
{Book cachedBook = redisBookStore.Get(isbn);if (cachedBook != null){return cachedBook;}Book book = service.GetByIsbn(isbn);redisBookStore.Put(isbn, book);return book;
}

通常来说,这里只是需要一个缓存,那么Redis也就只是这个缓存的一个具体实现,如果换为其他的NoSQL存储如Memcached呢?

因此,我们其实缺少了一个模型,在这里其实就是一个接口,假设这个接口如下:

public interface ICacheClient
{object Get(string key);void Put(string key, object value);
}

使用接口替代之后,我们就是面向接口编程了:

public Book GetByIsbn(string isbn)
{Book cachedBook = ICacheClient.Get(isbn);if (cachedBook != null){return cachedBook;}Book book = service.GetByIsbn(isbn);ICacheClient.Put(isbn, book);return book;
}

技术人喜欢用技术名词命名,因为这是大家习惯的语言。但是,对于业务项目而言,需要尽可能将技术术语隔离开,因为业务语言才是最好的命名方式

DDD领域驱动设计方法就号召我们建立统一语言,这个统一语言是可以和业务部门的人员无障碍交流的语言,换句话说,也就是业务语言。另一方面来看,这就倒逼技术团队需要建立团队的业务词汇表,让团队成员达成统一共识,这也是要统一共识需要付出的额外成本,但是这个成本是有价值的。

编写可维护的代码之路

比如,我们经常会写下面的参数命名:

public void ApproveChapter(long chapterId, long userId)
{...
}

假设通过业务分析,这里的user其实是审核人,而我们为了方便就命名为userId了。那么,将其改为reviewerUserId是不是更加贴近业务?

public void ApproveChapter(long chapterId, long reviewerUserId)
{...
}

在实际开发中,这样子的例子还有很多。

3乱用英语来命名

作为一个受了多年义务教育与高等教育的我们来说,English一点也不陌生,但是就是始终感觉用不到位。

如果能用中文来命名,我们是不会到处查单词用英文来命名的,但是,用中文,没有B格啊,我放弃!

违反语法规则的命名

类是一个名字,表示一个对象。而方法名一般是一个动词或动宾短语,表示一个动作。但是,有时候,我们喜欢忽视这个规则。

public void CompletedTranslate(List<string> chapterIds)
{List<Chapter> chapters = _repository.GetByChapterIds(chapterIds);chapters.ForEach(chapter => chapter.TranslationState = TranslationState.TRANSLATED);_repository.SaveChapters(chapters);
}

CompletedTranslate 是个啥(四不像结构)?改为 CompleteTranslation 是不是好一点(动宾结构)?

public void CompleteTranslation(List<string> chapterIds)
{......
}

又比如,一个方法名叫 ReTranslation(额,Translation好像是个名词吧),意为重新翻译,但作为方法名,应该选择动词,改为 ReTranslate 会更好(Translate是个动词,棒!)。

不准确的英语词汇

由于英文单词可以有多个含义,且在不同场景下含义也可以不同,这就难为我们中国人了。

比如,下面的一个枚举,想表达的是审核状态:

public enum ChapterAuditStatus
{PENDING,APPROVED,REJECTED
}

但是,Audit这个词虽然也有审核的含义,但是它更偏重于财务审计这块,而这里的业务是文稿的审核。

因此,改为Review可能会更加贴近一些:

public enum ChapterReviewStatus
{......
}

从上也可以看出,技术团队建立一个统一的业务词汇表,很有必要!这是集体的智慧,而非个体的。一个人的英语可能不太好,但是一群人在一起,总有那么一个会找出合适的说法。

英语单词拼写错误

这个,我相信大家各自项目中都有不少拼错的案例,很多人查了单词之后,都还是拼错...

但是,往往很多时候就是差了或者多了那么一个字母,就会让人懵逼了。

4小结

本文总结了命名相关的两类坏味道,一是命名是否具有业务含义,二是命名是否符合英语语法。

最后,感谢郑晔老师的这门《代码之丑》课程,让我受益匪浅!我也诚心把它推荐给关注EdisonTalk公众号的各位童鞋!

参考资料

郑晔,《代码之丑》(推荐订阅学习)

Martin Flower著,熊杰译,《重构:改善既有代码的设计》(推荐至少学习第三章)

????扫码订阅《代码之丑》

????点击购买《重构:改善既有代码的设计》

年终总结:Edison的2020年终总结

数字化转型:我在传统企业做数字化转型

C#刷题:C#刷剑指Offer算法题系列文章目录

技术管理:IT技术人的技术管理学习进阶

商业知识:IT技术人的底层商业知识兵器库

.NET大会:2020年中国.NET开发者大会PDF资料


????扫码关注EdisonTalk

不变的依旧是分享

代码 | 一天一点代码坏味道(1)相关推荐

  1. .NET代码质量 | 一天一点代码坏味道(4)

    [代码精进]| 总结/Edison Zhou 作为一个后端工程师,想必在职业生涯中都写过一些不好维护的代码.本文是我学习<代码之丑>的学习笔记,今天最后一天,一起品品滥用控制语句的味道,再 ...

  2. 在项目中寻找代码的坏味道(命名)

    介绍 这段时间一直做项目,所以相对忙碌些,今天终于有时间回过头来好好看一下自己写的代码,看哪里有问题,哪里有"坏味道". 慢慢过,慢慢回忆代码.开始捕捉坏味道. 常做的和常想的事情 ...

  3. 消除代码中的坏味道,编写高质量代码

    消除代码中的坏味道,编写高质量代码 Intro 想要写出较好的代码,保证代码的高质量需要时刻警惕代码中的坏味道,今天分享一下,我觉得平时写的代码中可能会出现的坏味道代码的一些示例 常见的坏味道代码 B ...

  4. 讲点码德!避免这些代码坏味道,努力做一名优秀的程序员

    Martin Fowler:任何一个傻瓜都能写出计算机可以理解的代码.唯有写出人类容易理解的代码,才是优秀的程序员. 大家闭着眼睛想一下什么是好代码?也许你的脑海中漂浮着一堆词:干净.整洁.命名规范. ...

  5. 代码坏味道之代码臃肿

    :notebook: 本文已归档到:「blog」 翻译自:sourcemaking.com/refactoring- 代码臃肿(Bloated)这组坏味道意味着:代码中的类.函数.字段没有经过合理的组 ...

  6. 讲点武德!避免这些代码坏味道,努力做一名优秀的程序员

    Martin Fowler:任何一个傻瓜都能写出计算机可以理解的代码.唯有写出人类容易理解的代码,才是优秀的程序员. 大家闭着眼睛想一下什么是好代码?也许你的脑海中漂浮着一堆词:干净.整洁.命名规范. ...

  7. java 代码坏味道_代码中的坏味道

    前言 在日常生活中,当我们买的水果放久了之后会发出一种难闻的气味("坏味道"),这个时候我们就应该把它扔掉.同样,代码也有"坏味道",当然确定什么是和不是代码& ...

  8. 重构 改善既有代码的设计:代码的坏

    以下内容来自<<重构 改善既有代码的设计>> 一.什么是重构 所谓重构(Refactoring)是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改以改进程序的内部结构 ...

  9. 不讲码德!坏味道偷袭我这个老码农

    作者 | 雷架 来源 | 爱笑的架构师(ID:DancingOnYourCode) 大家闭上眼睛想一下什么是好代码?也许你的脑海中漂浮着一堆词:干净.整洁.命名规范.注释合理.高内聚低耦合-- 人人都 ...

最新文章

  1. 开发者推出可重用地址提案提升BCH性能
  2. Android开发之动态添加控件
  3. matlab简单程序实例_【简单实例】如何使用C++加速python程序
  4. 函数动态参数实现format
  5. PHP 正则表达式资料
  6. Vue----常见面试题
  7. windows server 2016安装weblogic
  8. python自制网课答案查找器
  9. 罗马数字数字1到10对照表
  10. 整理了百大框架排行榜
  11. 获取手机或电脑GPS位置信息(定位平台)
  12. python中使用函数的优点是什么_python函数式编程是什么?
  13. oracle实例恢复 redo,ORACLE不完全恢复之current或active状态redo损坏(二)
  14. Origin | 一个X对应多个Y的折线图
  15. 合肥ibm服务器维修,合肥IBM/thinkpad笔记本维修
  16. javaWeb课程体系介绍
  17. 【转】我的技术学习方法 — Anytao
  18. 在word中使用Endnote
  19. (原创)23种设计模式一网打尽,看这篇就够了!
  20. web前端+HTML5+CSS3学习笔记

热门文章

  1. linux启动时挂载rootfs的几种方式 .
  2. sublime text3:提示 There are no packages available installation 解决方案
  3. E20171214-sl
  4. 【代码笔记】iOS-播放从网络上下载的语音
  5. 【.NET特供-第三季】ASP.NET MVC系列:传统WebForm站点和MVC站点执行机制对照
  6. jquery send(data) 对data的处理
  7. 轻松搭建Google ADK开发环境
  8. jQuery Pagination Ajax分页插件中文详解
  9. Microsoft Teams:删除成员账户其历史聊天会发生什么?
  10. 微软 word转换pdf_如何将行转换为Microsoft Word表中的列