设计模式之美
王争
前 Google 工程师,《数据结构与算法之美》专栏作者
123425 人已学习
新⼈⾸单¥98
登录后,你可以任选6讲全文学习
课程目录
已完结/共 113 讲
设计模式与范式:行为型 (18讲)
设计模式之美
15
15
1.0x
00:00/00:00
登录|注册

34 | 实战一(上):通过一段ID生成器代码,学习如何发现代码质量问题

性能和安全性
并发问题和线程安全
日志打印和接口易用性
逻辑的正确性和异常处理
业务需求的实现
代码的可读性
代码的可测试性
代码的扩展性和复用性
设计模式的应用
设计原则和设计思想
目录设置、模块划分、代码结构
发现代码质量问题的checklist
业务需求相关的问题
通用的关注点
代码质量问题
代码示例
实现需求背景
ID的概念及在软件开发中的应用
Logger对象的定义和影响
重点回顾
如何发现代码质量问题?
一份“能用”的代码实现
ID生成器需求背景介绍
课堂讨论
通过一段ID生成器代码,学习如何发现代码质量问题
参考文章

该思维导图由 AI 生成,仅供参考

在前面几节课中,我们讲了一些跟重构相关的理论知识,比如:持续重构、单元测试、代码的可测试性、解耦、编码规范。用一句话总结一下,重构就是发现代码质量问题,并且对其进行优化的过程。
前面的内容相对还是偏理论。今天,我就借助一个大家都很熟悉的 ID 生成器代码,给你展示一下重构的大致过程。整个内容分为两节课。这一节课我们讲述如何发现代码质量问题,下一节课讲述如何针对发现的质量问题,对其进行优化,将它从“能用”变得“好用”。
话不多说,让我们正式开始今天的学习吧!

ID 生成器需求背景介绍

“ID”中文翻译为“标识(Identifier)”。这个概念在生活、工作中随处可见,比如身份证、商品条形码、二维码、车牌号、驾照号。聚焦到软件开发中,ID 常用来表示一些业务信息的唯一标识,比如订单的单号或者数据库中的唯一主键,比如地址表中的 ID 字段(实际上是没有业务含义的,对用户来说是透明的,不需要关注)。
假设你正在参与一个后端业务系统的开发,为了方便在请求出错时排查问题,我们在编写代码的时候会在关键路径上打印日志。某个请求出错之后,我们希望能搜索出这个请求对应的所有日志,以此来查找问题的原因。而实际情况是,在日志文件中,不同请求的日志会交织在一起。如果没有东西来标识哪些日志属于同一个请求,我们就无法关联同一个请求的所有日志。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文总结了一段ID生成器代码的重构过程。首先介绍了ID生成器的需求背景,即为了在请求出错时排查问题,需要为每个请求分配一个唯一ID,并将其保存在请求的上下文中,以便在日志中关联同一个请求的所有日志。接着展示了一份“能用”的代码实现,但指出了其中存在的问题,如代码质量不高、可读性差、缺乏异常处理等。下文分析了代码质量问题的发现方法,包括通用的关注点和业务特定的需求。对代码进行了全面评价,指出了设计不合理、可测试性差、异常处理不当、可读性差等问题。最后,总结了如何发现代码质量问题的checklist,以及对Logger对象的依赖注入问题进行了讨论。整体内容涵盖了代码重构的实际案例和思路,适合读者快速了解文章概览,提升代码质量意识。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》
新⼈⾸单¥98
立即购买
登录 后留言

全部留言(70)

  • 最新
  • 精选
  • seckiller
    王争大佬以后课多带点实战代码

    作者回复: 这节课里的代码不就是吗

    2020-01-20
    11
  • 失火的夏天
    争哥,老实说,这个小王是不是曾经的你
    2020-01-20
    13
    171
  • 李小四
    设计模式_34 Logger的方法一般不会有未决行为,不影响可测试性,不用依赖注入。 以前看代码质量是看感觉,现在开始有章法了。
    2020-01-20
    4
    49
  • Jackey
    我要把这个checklist打印出来贴桌子上
    2020-01-20
    48
  • javaadu
    这个logger没有未决行为,不影响可测试性。我之前的一篇文章里提到过,将logger对象设置成static的原因是确保日志对象每个类一份、设置成final的原因是避免日志对象在运行时被修改。https://mp.weixin.qq.com/s/1OpvN8_dzIDWYBDiICU6yw
    2020-01-25
    1
    33
  • 氧气🌙 🐟 🌺
    1.split效率较低 2.随机字符的生成可用固定数组随机取数: int count = 0; String random = ""; char[] doc = { 'A', 'B', 'C', 'D', 'a', 'b', 'c','d','1','2','3' }; while (count < 8) { int index = (int) (Math.random() * doc.length); random = random + (doc[index]); count++; } System.out.println(random);
    2020-01-23
    1
    28
  • 未来小娃
    【设计模式笔记34】20200529 今天代码质量自查手册很实用,我看了评论有同学说要打印出来之类的,我觉得好东西就应该第一时间消化并想想怎么内化为自己的实践。结合前面学的设计原则和质量手册,我想了如下问题: 1、分了哪些模块,每个模块负责的事情是什么,满足单一职责么 2、具体某个模块分了哪些包,每个包放什么样的类,分类是否合理重复 3、具体到某个类,命名是否清晰简单,注释是否包含做什么、为什么做、如何做,API是否有如何用 4、类的属性有哪些,是否有魔数,属性结构是否统一,是否有非关联的属性,是否有大函数,每个函数的职责是否单一,某些函数是否可复用和抽象,是否可读 5、是否使用了设计模式,使用了什么设计模式,是否可以不用,如果非要用带来的好处是什么以及不用带来的坏处 6、如果要新增或者修改功能是否好扩展,是否满足开闭 7、某些函数是否可以复用,是否有现成的工具,强烈建议每个团队内部都有一个工具包 8、代码是否有异常会影响原有逻辑么,如果有怎么解决,想想兜底或者降级方案 9、是否有并发问题,如果出现了会有什么影响,怎么解决 10、代码是否有测试用例,是否覆盖了正常合异常的情况
    2020-05-29
    22
  • pedro
    争哥这一节跟马丁那本<重构>的第一章有异曲同工之妙。 如果大家觉得意犹未尽,可以尝试动手去学学重构的第一章,然后动手实践一下🤪
    2020-01-20
    17
  • 为什么说静态方法会影响代码的可测试性?
    2020-04-18
    5
    11
  • Frank
    学完这篇文章后,体会到之前学习的东西逐渐影响到自己后面的学习。这也验证了“你努力走过的路,每一步都算数”。在读文章的过程中,自己也思考了文中提供的代码有哪些问题,但是在读完文章后,发现自己并没有像文章中罗列的那套路来思考,自己都是按照之前学习的知识想到一点是一点,没有条理,没有章法。这也提醒了我该回炉重新去回顾以前学过的知识,要不断的进行思考总结将它们在自己的大脑里留下更深的记忆,并产生相关的连接。文中罗列的两个checkList,个人感觉很好用,通过这两个checkList,从“通用的代码关注点”和“业务功能、非功能需求”这两个维度思考将之前学习到的知识点都串联起来了,使我们能够学以致用。回顾自己以前在看自己的代码和别人的代码的时候,只是简单的看一些命名是否规范,是否可读等。感觉有内功又深了一层的感觉。 对于课堂讨论,Logger对象,个人觉得并不影响测试性,它只是一个辅助手段用于打印日志。也没必要通过依赖注入的方式构造对象,这一点耦合还是可以接受的。使用依赖注入为了是解耦,将依赖类在外部创建好,通过构造函数,函数参数方式传递来给类使用。
    2020-01-20
    8
收起评论
显示
设置
留言
70
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部