重构——改善既有代码的设计

embedded/2024/9/25 15:17:42/

目录

第一章:重构,第一个实例

第二章:重构的原则

第三章:代码坏味道

第四章:构筑测试体系

第五章:介绍重构名录

第六章:第一组重构

第七章:封装

第八章:搬移特性

第九章:重新组织数据

第十章:简化条件逻辑

第十一章:重构API

第十二章:处理继承关系


第一章:重构,第一个实例

  • 总结:通过一个简单的示例来理解重构的基本过程和效果

第二章:重构的原则

  • 总结:重构的定义、原则、以及重构与性能的关系
    • 何谓重构
      • 重构(名词):对软件内部结构的一种调整目的是不改变软件可观测行为的前提下,提高其可理解性,降低修改成本
      • 重构(动词):使用一系列的重构手法,在不改变软件可观测行为的前提下,调整其结构
      • 重构原则:时刻保持软件可用:如果有人说他们的代码在重构过程中有一两天的时间不可用,基本上可以确定,他们在做的事情不是重构
    • “两顶帽子”:添加新功能、调整代码结构
      • 开发的时候自己可能经常变换帽子
    • 为何重构
      • 重构改进软件的设计:经常性的重构有助于代码维持自己该有的形态并消除重复代码
      • 重构使软件更容易理解:代码不只给计算机用,还给其他的维护者用,经常的重构可以让人更能看懂代码的含义
      • 重构帮助找到 bug:对代码进行重构,我就可以深入理解代码的所作所为,并立即把新的理解反映在代码当中。搞清楚程序结构的同时,我也验证了自己所做的一些假设,于是想不把bug揪出来都难。(重构为驱动去理解代码?这里不是很理解
      • 重构提高编程速度:之前行业的陈规认为良好的设计必须在开始编程之前完成,因为开始编写代码后,设计就只会腐败,重构改变了这个图景。我们可以先做一个设计,然后随着需求的迭代不断改进它
    • 何时重构
      • 三次法则:事不过三,三则重构。第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是可以去做;第三次再做类似的事,你就应该重构
      • 预备性重构:让添加新功能更容易
      • 帮助理解的重构:使代码更易懂
      • 捡垃圾式重构:每个小步骤都不会破坏代码,就像捡垃圾一样,积少成多
    • 何时不应该重构
      • 不需要修改的代码:不需要修改的代码,就不需要重构它。只有当需要理解其工作原理时,对其进行重构才有价值 

第三章:代码坏味道

  • 总结:如何识别代码中不好的地方
    • 神秘命名:无法通过命名直观地知道变量或者方法的作用
    • 重复代码:设法将结构相似的代码合而为一,程序会变得更好。一旦有重复代码存在,阅读这些重复的代码时你就必须加倍仔细,留意其间细微的差异。如果要修改重复代码,你必须找出所有的副本来修改。如果重复的代码段位于同一个超类的不同子类中,可以使用函数上移来避免在两个子类之间互相调用。
    • 过长函数:函数的职责不够单一,导致直接违反开闭原则
      • 作者介绍了一条原则:每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立函数中,并以其用途(而非实现手法)命名
    • 过长参数列表:如果可以向某个参数发起查询而获得另一个参数的值,那么就以查询取代参数,去掉这第二个参数
      • 使用类可以有效地缩短参数列表。如果多个函数有同样的几个参数,引入一个类就尤为有意义
    • 全局数据:全局数据代表全局任何一个地方都可以改变他而不受监控,一般需要通过封装变量的方式将这种全局的数据进行封装,通过方法进行改变
      • 封装变量的好处:1. 利于监控与定位问题 2. 如果这个变量需要跟一些协同变量同时改变,函数可以做到收口
    • 可变数据:尽量将查询和修改函数分开
    • 发散式变化:某个模块经常因为不同的原因在不同的方向上发生变化,这就意味着这个模块已经违反了单一职责原则,需要进行分割
    • 霰弹式修改:每次遇到某种变化,你必须在很多不同的类中进行小幅修改,这就说明你的模块拆分的过细
    • 依恋情结:一个函数跟另外的模块的函数或者数据交流格外频繁,远胜于自己所处模块内部的交流。应该将这个函数跟另外的模块放到一起
    • 数据泥团:如果你能在多个函数的参数中看到几个字段经常一起出现,这就是典型的数据泥团,应该将这些字段封装成类进行传递
      • 好处是可以将很多参数列表缩短,简化函数调用
      • 评判方法:删掉众多数据中的一项。如果这么做,其他数据不再有意义,这就是一个明确信号:你应该为它们产生一个新对象
    • 基本类型偏执:比如区号、血型等业务逻辑,不要单纯的用 string 去表示这种类型,可以通过封装对象的方式取代基本数据类型进行业务逻辑表达
      • 病症:
        • 不愿意创建对自己问题域有用的基本类型,如钱、坐标、范围等
        • 使用字符串做所有的事情
      • 解决:用对象取代基本类型,将原本单独存在的数据值替换为对象
    • 重复的 switch:用多态替代重复的 switch
    • 循环语句:作者提倡使用管道(比如 js 的 map filter等操作符)取代循环(但是我不认为循环就是个坏味道)
    • 夸夸其谈的通用性:即过度设计
    • 临时字段:特定情况临时加的
    • 过大的类:类的职责过度,需要进行拆分
    • 被拒绝的遗赠:如果拒绝父类的实现&接口,那继承父类就完全没有意义,不如通过以委托取代子类去代替继承关系
    • 注释:注释意味着这里的函数可以再次拆分成更小的函数 & 函数的命名可以再次优化。这里并不是说完全不可以写注释

第四章:构筑测试体系

  • 总结:要正确地进行重构,前提是得有一套稳固的测试集合
  • 自测case的一些原则
    • 让所有的测试都完全自动化,让它们自己检查测试结果
    • 一套测试就是一个强大的 bug 侦测器,能够大大缩减查找 bug 所需的时间
    • 总是确保测试case在不该通过时真的会失败
    • 频繁地运行测试,对于你正在处理的代码,与其对应的测试至少每隔几分钟就要运行一次,每天至少运行一遍所有的测试
    • 测试 case 不要求过度完美,编写未臻完善的测试并经常运行,好过对完美测试的无尽等待。
    • 将UI与业务逻辑隔离,这样才能写测试用例直接测逻辑部分
    • 考虑可能出错的边界,把测试火力集中到那里
      • 不断探索程序的错误边界反过来可以提高我们正向编程的能力
    • 不要幻想把所有场景都覆盖测试,只覆盖那些关键、容易出错的地方就够了,不然会因为工作量太大而气馁
    • 每当你收到一个 bug 时,请先写一个单元测试来暴露这个问题 

第五章:介绍重构名录

第六章:第一组重构

第七章:封装

重构改善既有代码的设计-学习(一):封装-CSDN博客

第八章:搬移特性

重构改善既有代码的设计-学习(二):搬移特性-CSDN博客

第九章:重新组织数据

重构改善既有代码的设计-学习(三):重新组织数据-CSDN博客

第十章:简化条件逻辑

重构改善既有代码的设计-学习(四):简化条件逻辑-CSDN博客

第十一章:重构API

重构改善既有代码的设计-学习(五):重构API-CSDN博客

第十二章:处理继承关系

重构改善既有代码的设计-学习(六):处理继承关系-CSDN博客


http://www.ppmy.cn/embedded/29534.html

相关文章

14.集合、常见的数据结构

集合 概念 Java中的集合就是一个容器,用来存放Java对象。 集合在存放对象的时候,不同的容器,存放的方法实现是不一样的, Java中将这些不同实现的容器,往上抽取就形成了Java的集合体系。 Java集合中的根接口&#x…

PostgreSQL自带的命令行工具02- createdb

PostgreSQL自带的命令行工具02- createdb 基础信息 OS版本:Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本:16.2 pg软件目录:/home/pg16/soft pg数据目录:/home/pg16/data 端口:5777createdb 是 Postgr…

鸿蒙学习1概况

鸿蒙学习1相关概念 前言相关概念Stage 模型1. AbilityStage2. UIAbility组件和ExtensionAbility组3. WindowStage4. Context 事件传递UIAbility组件与UI的数据同步UIAbility组件间交互(设备内) 进程模型线程模型 前言 有时间多看官网,官网的…

零知识证明与同态加密:隐私计算的双剑

PrimiHub一款由密码学专家团队打造的开源隐私计算平台,专注于分享数据安全、密码学、联邦学习、同态加密等隐私计算领域的技术和内容。 在数字时代,隐私保护已成为全球关注的焦点。隐私计算作为解决数据隐私问题的关键技术,其核心目标是在不泄…

【C++ 问题总结】

C问题总结 C问题解决1.C两种实用方式解决clion不能运行多个main文件1.下载插件1.1下载插件,C/C Single File Execution1.2删除CMakeLists.txt文件中的add_executable()1.3在新建的cpp文件中,右击 --> 点击Add executable for single c/cpp file -->…

附录6-4 黑马优购项目-分类和购物车

目录 1 分类 1.1 接口 1.2 窗口限制 1.3 选中状态样式判断 1.4 点击左侧时右侧会到顶点 1.5 源码 2 购物车 2.1 store 2.2 tabBar徽标 2.3 滑动删除 2.4 结算 2.4.1 结算前登录 2.4.2 结算功能 2.5 触发组件事件 2.6 源码 1 分类 分类最上部是…

什么是oneflow

一,什么是OneFlow? OneFlow是一个用于机器学习的开源软件框架,它允许研究人员和开发人员设计、训练和部署机器学习模型。机器学习是人工智能的一个分支,它使计算机能够从数据中学习并做出预测或决策,而不需要明确编程…

docker各目录含义

目录含义builder构建docker镜像的工具或过程buildkit用于构建和打包容器镜像,官方构建引擎,支持多阶段构建、缓存管理、并行化构建和多平台构建等功能containerd负责容器生命周期管理,能起、停、重启,确保容器运行。负责镜管理&am…