重构—对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
代码坏味道
|
常用重构手段
|
Duplicated重复代码
|
Extract Method
Extract Class
Pull Up Method
Form Template Method
|
Long Method 过长函数
|
Extract Method
Replace Temp With Query
Replace Method With Method Object
Decompose Conditional
|
Large Class 过大的类
|
Extract Class
Extract Subclass
Extract Interface
Replace Data Value With Object
|
Long Parameter List 过长参数列
|
Replace Parameter With Method
Introduce Parameter Object
Preserve Whole Object
|
Divergent Change 发散式变化
|
Extract Class
|
Shotgun Surgery散弹式修改
|
Move Method
Move Field
Inline Class
|
Feature Envy 依恋情结
|
Move Method
Move Field
Extract Method
|
Data Clumps 数据泥团
|
Extract Class
Introduce Parameter Object
Preserve Whole Object
|
Primitive Obsession 基本类型偏执
|
Replace Data Value With Object
Extract Class
Introduce Parameter Object
Replace Array with Object
Replace Type Code With Class
Replace Type Code With Subclasses
Replace Type Code With State/Strategy
|
Switch Statements switch惊悚现身
|
Replace Conditional With Polymorphisrn
Replace Type Code With Subclasses
Replace Type Code With State/Strategy
Replace Parameter With Explicit Methods
Introduce Null Object
|
Parallel Inheritance Hierarchies 平行继承体系
|
Move Method
Move Field
|
Lazy Class 冗赘类
|
Inline Class
Collapse Hierarchy
|
Speculative Generality 夸夸其谈未来性
|
Collapse Hierarchy
Inline Class
Remove Parameter
Rename Method
|
Temporary Field 令人迷惑的暂时字段
|
Extract Class
Introduce Null Object
|
Message Chains 过度耦合的消息链
|
Hide Delegate
|
Middle Man 中间人
|
Remove Middle Man
Inline Method
Replace Delegation With Inheritance
|
Inappropriate Intimacy 狎昵关系
|
Move Method
Move Field
Change Bidirectional Association to Unidirectional
Replace Inheritance With Delegation
Hide Delegate
|
Alternative Classes with Different Interfaces 异曲同工的类
|
Rename Method
Move Method
|
Incomplete Library Class 不完美的库类
|
Introduce Foreign Method
Introduce Local Extension
|
Data Class 纯稚的数据类
|
Move Method
Encapsulate Field
Encapsulate Colletion
|
Refused Bequest 被拒绝的遗赠
|
Replace Inheritance With Delegation
|
Comments 过多的注释
|
Extract Method
Introduce Assertion
|
重构列表:
l 重新组织函数
Ø Extract Method(提取函数)
有一段代码可以被组织在一起并独立出来
将这段代码放进一个独立函数中,并让函数名称解释该函数的用途
Ø Inline Method(将函数)
一个函数,其本地应该与其名称同样清楚易懂
在函数调用点插入函数本地,然后移除该函数
Ø Inline Temp(将临时变量内联化)
有一个变量,只被一个简单表达式赋值一次,而它妨碍了其他重构手法
将所有对该变量的引用动作,替换为对它赋值的那个表达式本身
Ø Replace Temp With Query(以查询取代临时变量)
程序以一个临时变量保存某一表达式的运算结果
将这个表达式提炼到一个独立函数中,将这个临时变量的所有被引用点替换为对新函数的调用。新函数可被其他函数使用
Ø Introduce Explaining Variable(引入解释性变量)
有一个复杂的表达式
将该表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途
Ø Split Temporary Variable(剖解临时变量)
程序有某个临时变量被赋值超过一次,它既不是循环变量,也不是一个集用临时变量
针对每次赋值,创造一个独立的、对应的临时变量
Ø Remove Assignments to Parameters(移除对参数的赋值动作)
代码对一个参数进行赋值动作
以一个临时变量取代该参数的位置
Ø Replace Method With Method Object(以函数对象取代函数)
有一个大型函数,其中对局部变量的使用,使得无法采用Extract Method
将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的值域,然后可以再同一个对象中将这个大型函数分解为数个小型函数
Ø Substitute Algorithm(替换算法)
把某个算法替换为另一个更清晰的算法
将函数本体替换为另一个算法
l 在对象之间搬移特性
Ø Move Method(搬移函数)
在程序中,有个函数与其所驻class之外的另一个class进行更多交流:调用后者,或被后者调用
Ø Move Field(搬移值域)
在程序中,某个field被其所驻class之外的另一个class更多地用到
在target class建立一个new field,修改source field的所有用户,令它们改用此new field
Ø Extract Class(提炼类)
某个class做了应该由两个classes做的事
建立一个新class,将相关的值域和函数从旧class搬移到新class
Ø Inline Class(将类内联化)
某个class没有做太多的事情(没有承担足够责任)
将class的所有特性搬移到另一个class中,然后移除原class
Ø Hide Delegate(隐藏委托关系)
客户直接调用其server object的delegate class
在server端建立客户所需的所有函数,用以隐藏委托关系
Ø Remove Middle Man(移除中间人)
某个class做了过多的简单委托动作
让客户直接调用delegate
Ø Introduce Foreign Method(引入外加函数)
所使用的server class需要一个额外函数,但无法修改这个class
在client class中建立一个函数,并以一个server class实体作为第一参数
Ø Introduce Local Extension(引入本地扩展)
使用的server class需要一些额外函数,但无法修改这个class
建立一个新class,使它包含这些额外函数。让这个扩展品成为source class的subclass或wrapper
l 重新组织数据
Ø Self Encapsulate Field(自封装值域)
直接访问一个field,但与值域之间的耦合关系逐渐变得笨拙
为这个值域建立取值/设置函数,并且只以这些函数来访问值域
Ø Replace Data Value With Object(以对象取代数据值)
有一笔数据项(data item),需要额外的数据和行为
将这笔数据项变成一个对象
Ø Change Value to Reference(将实值对象改为引用对象)
有一个class,衍生出许多相等尸体,希望将它们替换为单一对象
将这个value object变成一个reference object
Ø Change Reference to Value(将引用对象改为实值对象)
有一个reference object,很小且不可变,而且不易管理
将它变成一个value object
Ø Replace Array With Object(以对象取代数组)
有一个数组,其中的元素各自代表不同的东西
以对象替换数组。对于数组中的每个元素,以一个值域表示之
Ø Duplicate Observed Data(复制被监视数据)
有一些domain class置身于GUI控件中,而domain method需要访问之
将改笔数据拷贝到一个domain object中。建立一个Observer模式,用以对domain object和GUI object内的重复数据进行同步控制
Ø Change Unidirectional Association to Bidirectional(将单向关联改为双向)
两个classes都需要使用对方特性,但其间只有一条单向连接
添加一个反向指针,并使修改函数能够同时更新两条连接
Ø Change Bidirectional Association to Unidirectional(将双向关联改为单向)
两个classes之间有双向关联,但其中一个class如今不再需要另一个class的特性
去除不必要的关联
Ø Replace Magic Number With Symbolic Constant(以符号常量/字面常量取代魔法数)
有一个字面数值,带有特别含义
创造一个常量,根据其意义为它命名,并将上述的字面数值替换为这个常量
Ø Encapsulate Field(封装值域)
Class中存在一个public值域
将它声明为private,并提供相应的访问函数
Ø Replace Record With Data Class(以数据类取代记录)
需要面对传统编程环境中的record structure
为该record创建一个哑数据对象(dumb data object)
Ø Replace Type Code With Class(以类取代型别码)
Class之中有一个数值型别码,但它并不影响class的行为
以一个新的class替换该数值型别码
Ø Replace Type Code With Subclasses(以子类取代型别码)
有一个不可变的type code,它会影响class的行为
以一个subclass取代这个type code
Ø Replace Type Code With State/Strategy(以State/Strategy取代型别码)
有一个type code,它会影响class的行为,但无法使用subclassing
以state object取代type code
Ø Replace Subclass With Fields(以值域取代子类)
各个subclasses的惟一差别只在返回常量数据的函数身上
修改这些函数,使它们返回superclass中的某个(新增)值域,然后销毁subclasses
l 简化条件表达式
Ø Decompose Conditional(分解条件式)
有一个复杂的条件(if-then-else)语句
从if、then、else三个段落中分别提炼出独立函数
Ø Consolidate Conditional Expression(合并条件式)
有一系列条件测试,都得到相同结果
将这些测试合并为一个条件式,并将这个条件式提炼成为一个独立函数
Ø Consolidate Duplicate Conditional Fragments(合并重复的条件片段)
在条件式的每个分支上有着相同的一段代码
将这段重复代码搬移到条件式之外
Ø Remove Control Flag(移除控制标记)
在一系列布尔表达式中,某个变量带有控制标记(control flag)的作用
以break语句或return语句取代控制标记
Ø Replace Nested Conditional With Guard Clauses(以卫语句取代嵌套条件式)
函数中的条件使人难以看清正常的执行路径
使用卫语句(guard clauses)表现所有特殊情况
Ø Replace Conditional With Polymorphism(以多态取代条件式)
有个条件式,它根据对象类别的不同而选择不同的行为
将这个条件式的每个分支放进一个subclass内的覆写函数中,然后将原始函数声明为抽象函数
Ø Introduce Null Object(引入Null对象)
需要再三检查某物是否为null value
将null value替换为null object
Ø Introduce Assertion(引入断言)
某一段代码需要对程序状态做出某种假设
以assertion明确表现这种假设
l 简化函数调用
Ø Rename Method(重新命名函数)
函数的名称未能揭示函数的用途
修改函数名称
Ø Add Parameter(添加参数)
某个函数需要从调用端得到更多信息
为此函数添加一个对象函数,让该对象带函数所需信息
Ø Remove Parameter(移除参数)
函数本体不再需要某个函数
将该函数去除
Ø Separate Query from Modifier(将查询函数和修改函数分离)
某个函数既返回对象状态值,又修改对象状态
建立两个不同的函数,其中一个负责查询,另一个负责修改
Ø Parameterize Method(令函数携带参数)
若干函数做了类似的工作,但在函数本体中却包含了不同的值
建立单一函数,以参数表达那些不同的值
Ø Replace Parameter With Explicit Methods(以明确函数取代参数)
有一个函数,其内完全取决于参数值而采取不同反应
针对该参数的每一个可能值,建立一个独立函数
Ø Preserve Whole Object(保持对象完整)
从某个对象中取出若干值,将它们作为某一次函数调用时的参数
改使用(传递)整个对象
Ø Replace Parameter With Method(以函数取代参数)
对象调用某个函数,并将所得结果作为参数,传递给另一个函数。而接受该参数的函数也可以(也有能力)调用前一个函数
让参数接受者去除该项参数,并直接调用前一个函数
Ø Introduce Parameter Object(引入参数对象)
某些参数总是很自然地同时出现
以一个对象取代这些参数
Ø Remove Setting Method(移除设置函数)
Class中的某个域值,应该在对象初创时被设置,然后就不再改变
去掉该值域的所有设值函数
Ø Hide Method(隐藏某个函数)
有一个函数,从来没有被其他任何class用到
将这个函数修改为private
Ø Replace Constructor With Factory Method(以工厂函数取代构造函数)
希望在创建对象时不仅仅是对它做简单的建构动作
将constructor替换为factory method
Ø Encapsulate Downcast(封装向下转型动作)
某个函数返回的对象,需要由函数调用者执行向下转型动作
将向下转型动作移到函数中
Ø Replace Error Code With Exception(用异常取代错误码)
某个函数返回一个特定的代码,用以表示某种错误情况
改用异常
Ø Replace Exception With Test(以测试取代异常)
面对一个调用者可预先加以检查的条件,抛出一个异常
修改调用者,使它在调用函数之前先做检查
l 处理概括关系
Ø Pull Up Field(值域上移)
两个subclasses拥有相同的值域
将此值域移至superclass
Ø Pull Up Method(函数上移)
有些函数,在各个subclass中产生完全相同的结果
将该函数移至superclass
Ø Pull Up Constructor Body(构造函数本体上移)
在各个subclass中拥有一些构造函数,它们的本体代码几乎完全一致
在superclass中新建一个构造函数,并在subclass构造函数中调用它
Ø Push Down Method(函数下移)
Superclass中的某个函数只与部分(而非全部)subclasses有关
将这个函数移到相关的那些subclasses去
Ø Push Down Field(值域下移)
Superclass中的某个值域只被部分(而非全部)subclasses用到
将这个值域移到需要它的那些subclasses去
Ø Extract Subclass(提炼子类)
Class中的某些特性只被某些(而非全部)实体用到
新建一个subclass,将上面所说的那一部分特性移到subclass中
Ø Extract Superclass(提炼超类)
两个classes有相似特性
为这两个classes建立一个superclass,将相同特性移至superclass
Ø Extract Interface(提炼接口)
若干客户使用class接口中的同一子集;或者,两个classes的接口有部分相同
将相同的子集提炼到一个独立接口中
Ø Collapse Hierarchy(折叠继承关系)
Superclass和subclass之间无太大区别
将它们合为一体
Ø Form Template Method(塑造模板函数)
有一些subclasses,其中相应的某些函数以相同顺序执行类似的措施,但各措施实际上有所不同
将各个措施分别放进独立函数中,并保持它们都有相同的签名式(signature),于是原函数也就变得相同了。然后将原函数上移至superclass
Ø Replace Inheritance with Delegation(以委托取代继承)
某个subclass只使用superclass接口中的一部分,或是根本不需要继承而来的数据
在subclass中新建一个值域用以保存superclass;调整subclass函数,令它改而委托superclass;然后去掉两者之间的继承关系
Ø Replace Delegation With Inheritance(以继承取代委托)
在两个classes之间使用委托关系,并经常为整个接口编写许多极简单的请托函数
让请托(delegating)class继承受托class
l 大型重构
Ø Tease Apart Inheritance(梳理并分解继承体系)
某个继承体系同时承担两项责任
建立两个继承体系,并通过委托关系让其中一个可以调用另一个
Ø Convert Procedural Design to Objects(将过程化设计转化为对象设计)
有一些代码,以流程的过程化风格写就
将数据记录变成对象,将行为分开,并将行为移入相关对象之中
Ø Separate Domain from Presentation(将领域和表述/显示分离)
某些GUI class之中包含了domain logic(领域逻辑)
将domain logic分离出来,为它们建立独立的domain class
Ø Extract Hierarchy(提炼继承体系)
某个class做了太多工作,其中一部分工作以大量条件式完成
建立继承体系,以一个subclass表示一种特殊情况
分享到:
相关推荐
软件定义和硬件重构概述 软件定义和硬件重构是当前数据中心建设的两个主要趋势。软件定义强调通过软件来管理和控制网络架构,而硬件重构则强调通过硬件来实现网络架构的变化。这些趋势是应对快速增长的业务需求和...
城市居民最低生活保障制度的评估与重构概述.pptx
在大数据背景下,财务管理与分析体系正经历着深刻的重构。这一变革不仅仅是技术层面的升级,更是思维方式和商业模式的根本转变。薛素文在2009年和2015年的观点揭示了移动互联网和“互联网+”对传统行业带来的冲击,...
#### 一、架构重构概述 架构重构是指为了改善现有软件系统的结构,提升其可维护性和扩展性,而不改变其外部行为的过程。随着业务的发展和技术的进步,原有的架构可能会出现各种“坏味道”,即一些设计上的不合理之...
#### 一、二维小波分解与重构概述 二维小波变换是图像处理领域中一种重要的数学工具,主要用于图像压缩、去噪、特征提取等方面。它通过将图像分解成不同分辨率的子带(如低频、水平高频、垂直高频和对角高频),实现...
#### 一、Oracle索引重构概述 在日常的数据库维护工作中,我们可能会遇到数据库中的索引变得杂乱无章的情况。这种情况可能会导致查询性能下降,因此对索引进行重构是非常必要的。Oracle提供了多种方法来帮助我们...
#### 二、重构概述 ##### 2.1 重构的概念 重构是由Ralph Johnson等人首次提出的概念,并在William E. Opdyke的博士论文中进行了深入的研究和发展。重构的主要目标是改善软件的内部结构,提高其灵活性、可维护性和...
#### 一、重构概述与重要性 重构是软件开发过程中一个重要的环节,指的是在不改变软件外部行为的前提下,通过改进内部结构来提高代码质量和可维护性的过程。这一概念最早由马丁·福勒(Martin Fowler)等人在《重构...
#### 一、重构概述 重构是软件开发过程中不可或缺的一部分,它指的是在不改变软件外部行为的前提下,对其内部结构进行调整的过程。这一过程通常伴随着代码质量的提高,使其更加易于理解、维护和扩展。《31天重构...
#### 二、重构概述与重要性 重构是指在不改变软件外部行为的前提下,对代码进行修改的过程。这个过程旨在改善代码结构,使其更加清晰、高效且易于维护。重构的重要性体现在以下几个方面: 1. **提高代码质量**:...
**重构概述**:软件重构是一种在不改变软件外部行为的前提下,改进其内部结构和设计的过程。重构的目标是提高代码的可读性、可维护性和性能。 **重构原因**: - 提高代码的可读性和可维护性。 - 改善代码质量,减少...
**代码重构概述** 代码重构是指在不改变外部行为的前提下,对现有代码进行结构上的修改,以提高其内部质量的过程。目标是在保持原有功能的基础上,提高代码的可读性、可维护性和扩展性。 **代码重构原则** - **...
#### 第2章 软件代码重构概述 **软件代码重构**是一种软件工程实践活动,目的是在不改变软件外部行为的前提下,优化内部结构,提升代码质量。 - **定义与目的** - **定义**:重构是对现有代码进行改造,改进其...
#### 二、数据中心重构概述 数据中心重构是指通过对现有数据中心基础设施和技术架构进行全面升级和改造,以提高其性能、灵活性和效率的过程。这一过程通常包括硬件更新、软件定义基础架构(SDI)的实施、自动化流程的...
【通用汽车公司战略重构概述】 美国通用汽车公司在1990年代初遭遇了前所未有的危机,连续三年的巨大亏损使得这家全球知名企业面临破产的威胁。在关键时期,通用汽车选择了内部人才Jack Smith担任总裁,实施了一场名...
概述: 本文档介绍了阿里云新零售事业部的新零售形态,强调了以消费者体验为中心的数据驱动的新零售形态。通过阿里云的技术和平台,实现了零售业态的重构和升级,提高了零售业态的效率和体验。 知识点1:新零售...