# codereview **Repository Path**: xrw84/codereview ## Basic Information - **Project Name**: codereview - **Description**: 重构,改善既有代码的设计(java实现) - **Primary Language**: Java - **License**: MulanPSL-1.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2020-06-29 - **Last Updated**: 2023-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # codereview #### 介绍 重构,改善既有代码的设计(java实现) #### Chapter.2 重构的原则 ##### 2.1 何谓重构 `重构就是将复杂冗长的代码,修改成更容易理解,更容易维护的代码,每一个小功能的重构,不会影响程序的运行。` ##### 2.2 两顶帽子 `“两顶帽子”是指添加新功能和重构。在开发过程中,两顶帽子是可以随时切换的,重构并不是只能在功能开发完成之后进行, 在开发过程中,可能觉得调整代码结构,新功能可能更好的实现。` ##### 2.3 何为重构 `重构是一个工具,它可以用于以下几个目的` 1. 重构改进软件的设计 > 通过重构,我们能够更好的理解架构的整体设计,更加清晰的表达出设计的意图,良好的设计能狗更好的修改和维护。 2. 重构使软件更容易理解 > 重构使结构理想,能够让机器和其他读者更好的阅读代码。 3. 重构帮助找到bug > 结构清晰,能够更好的进行调试,知道每一步的所作所为,bug自然就找出来了 4. 重构提高编程速度 > 重构提高编程速度并不是说在开发的过程和结束,而是指,在有新功能或者bug修改的时候,我们能清楚的知道代码的功能,使之添加和修改时只需花费少量的时间。 ##### 2.4 何时重构 三次法则:事不过三,三则重构 1. 预备性重构:让添加新功能更容易 2. 帮助理解的重构:使代码更易懂 3. 捡垃圾式重构 4. 有计划的重构和见机行事的重构 5. 长期重构 6. 复审代码时重构 7. 何时不应该重构 > 不需要理解代码工作原理时,我们可以不重构 > 如果重写时间比重构时间短,我们不重构 ##### 2.5 重构的挑战 1. 延缓新功能开发 2. 代码所有权 3. 分支 4. 测试 5. 遗留代码 6. 数据库 ##### 2.6 重构、架构和YAGNI ##### 2.7 重构与软件开发过程 ##### 2.8 重构与性能 ##### 2.9 重构起源何处 ##### 2.10 自动化重构 ##### 2.11 延展阅读 #### Chapter.3 代码的坏味道 ##### 3.1 神秘命名(Mysterious Name) > 好的名字(函数、模块、变量和类名)能够清晰的表明自己的功能和用法 ##### 3.2 重复代码(Duplicated Code) > 相同的代码结构在多个地方出现,那么可以设法将它们合而为一。但是重复的代码也要留意其间细微的差异。最单纯的重复代码就是 >“同一个类的两个函数含有相同的表达式”。这时可以采用**提炼函数**提炼出重复的代码。如果重复的代码只是相似,可以尝试**移动语句** >重组代码顺序。如果重复的代码段位于同一个超类的不同子类中,可以使用**函数上移**来避免两个子类之间互相调用。 ##### 3.3 过长函数(Long Function) > 小函数能够带来更好的阐述力、更易于分享、更多的选择,让小函数易于理解的关键还是在于良好的命名。 > 如果一段代码需要用注释来说明的时候,我们就可以将其说明的代码提取为一个函数。 > 当你尝试用**提炼函数**的时候,如果函数中有大量的参数和临时变量,我们可以运用**查询取代临时变量**来消除这些临时元素。 >**引用参数对象**和**保持对象完整**则可以将过长的参数列表变得简洁一些,如果这么做了,还是有太多的临时变量和参数,我们就可以使用**命令取代函数** > 条件表达式和循环也是提炼的信号,我们可以使用**分解条件表达式处**理条件表达式。对于庞大的switch语句,其中的每个分支都应该通过**提炼函数** >变成独立的函数调用。如果多个switch语句基于同一个条件进行分支选择,我们可以使用**多态取代条件表达式**。 >针对循环,我们可以将循环和循环内的代码提炼到一个独立的函数中,提炼出的循环很难命名,可能是因为其中做了几件不同的事。我们可以使用**拆分循环**将其拆分为独立的任务 ##### 3.4 过长参数列表(Long Parameter List) ##### 3.5 全局数据(Gloable Data) ##### 3.6 可变数据(Mutable Data) ##### 3.7 发散式修改(Divergent Change) ##### 3.8 霰弹式修改(Shotgun Surgery) ##### 3.9 依恋情结(Feature Envy) ##### 3.10 数据泥团(Data Clumps) ##### 3.11 基本类型偏执(Primitive Obsession) ##### 3.12 重复的switch(Repeated Switches) ##### 3.13 循环语句(Loops) ##### 3.14 冗赘的元素(Lazy Element) ##### 3.15 夸夸其谈通用性(Speculative Generality) ##### 3.16 临时字段(Temporary Field) ##### 3.17 过长的消息链(Message Chains) ##### 3.18 中间人(Middle Man) ##### 3.19 内幕交易(Insider Trading) ##### 3.20 过大的类(Large Class) ##### 3.21 异曲同工的类(Alternative Classes with Different Interfaces) ##### 3.22 纯数据类(Data Class) ##### 3.23 被拒绝的遗赠(Refused Bequest) ##### 3.24 注释(Comments) #### Chapter.4 构筑测试体系 ##### 4.1 自测试代码的价值 ##### 4.2 待测试的示例代码 ##### 4.3 第一个测试 ##### 4.4 再添加一个测试 ##### 4.5 修改测试夹具 ##### 4.6 探测边界条件 ##### 4.7 测试远不止如此