第二十四章 重构

重构简介

重构定义:

  1. 在不改变软件外部行为的前提下,对其内部结构进行改变,使之更容易理解以便于修改;
  2. 尽可能地将一个程序分解为多个组成部分。

重构的理由

  • 代码重复;
  • 冗长的子程序;
  • 循环过长或嵌套过深;
  • 类的接口未能提供层次一致的抽象;
  • 拥有太多参数的参数列表;
  • 类的内部修改往往被局限于某个部分;
  • 变化导致对多个类的相同修改;
  • 对继承体系的同样修改;
  • case语句需要做相同的修改;
  • 同时使用的相关数据并未以类的方式进行组织;
  • 成员函数使用其他类的特征比使用自身类的特征还要多;
  • 过多使用基本数据类型;
  • 某个类无所事事;
  • 一系列传递流浪数据的子程序;
  • 中间人对象无事可做;
  • 某个类同其他类关系过于亲密;
  • 子程序命名不当;
  • 数据成员被设置为公用;
  • 某个派生类仅使用了基类的很少一部分成员函数;
  • 注释被用于解释难懂的代码;
  • 使用了全局变量;
  • 在子程序调用前使用了设置代码,或在调用后使用了收尾代码;
  • 程序中的一些代码似乎是在将来的某个时候才会用到的。

特定的重构

数据级的重构

  • 用具名常量替代神秘数值;
  • 使变量的名字更为清晰且传递更多信息;
  • 将表示内联化;
  • 用函数来代替表达式;
  • 引入中间变量;
  • 用多个单一用途变量代替某个多用途变量;
  • 在局部用途中使用局部变量而不是参数;
  • 将基础数据类型转化为类;
  • 将一组类型码转化为类或枚举类型;
  • 将一组类型码转换为一个基类及其相应派生类;
  • 将组数转换为对象;
  • 把集群封装起来;
  • 用数据类来代替传统记录。

语句级的重构

  • 分解布尔表达式;
  • 将复杂布尔表达式转换成命名准确的布尔表函数;
  • 合并条件语句不同部分中的重复代码片段;
  • 使用breakreturn而不是循环控制变量;
  • 在嵌套的if-then-else语句中一旦知道答案就立即返回,而不是去赋一个返回值;
  • 用多态来替代条件语句;
  • 创建和使用null对象而不是去检测空值。

子程序级重构

  • 提取子程序或者方法;
  • 将子程序的代码内联化;
  • 将冗长的子程序转换为类;
  • 用简单算法替代复杂算法;
  • 增加参数;
  • 删除参数;
  • 将查询操作从修改操作中独立出来;
  • 合并相似的子程序,通过参数区分他们的功能;
  • 将行为取决于参数的子程序拆分开来;
  • 传递整个对象而非特定成员;
  • 传递特定成员而非整个对象;
  • 包装向下转型的操作。

类实现的操作

  • 将值对象转化为引用对象;
  • 用数据初始化代替虚函数;
  • 改变成员函数或成员数据的位置;
  • 将特数代码提取为派生类;
  • 将相似的代码结合起来放置到基类中。

类接口的重构

  • 将成员函数放到另一个类中;
  • 将一个类变成两个;
  • 删除类;
  • 去除委托关系;
  • 去掉中间人;
  • 用委托代替继承;
  • 引入外部成员函数;
  • 引入扩展类;
  • 对暴露在外的成员变量进行封装;
  • 对于不能修改的类成员,删除相关的Set()成员函数;
  • 隐藏那些不会在类之外被用到的成员函数;
  • 封装不使用的成员函数;
  • 合并那些实现非常类似的基类和派生类。

系统级重构

  • 为无法控制的数据创建明确的索引源;
  • 将单向的类联系改为双向的类联系;将双向的类联系改为单向的类联系;
  • 用Factory Method模式而不是简单地构造函数;
  • 用异常取代错误处理代码,或者做相反方向的变换。

安全的重构

  • 保存初始代码;
  • 重构的步伐请小些;
  • 把要做的事情一条条列出来;
  • 设置一个停车场;
  • 多使用检查点;
  • 利用编译器警告信息;
  • 重新测试;
  • 增加测试用例;
  • 检查对代码的修改;
  • 根据重构风险级别来调整重构方法;

不宜重构的情况

  • 不要把重构当做险些后改的代名词;
  • 避免用重构代替重写。

重构策略

  • 在增加子程序时进行重构;
  • 在添加类的时候进行重构;
  • 在修补缺陷的时候进行重构;
  • 关注易于出错的模块;
  • 关注高度复杂的模块;
  • 在维护环境下改善你手中正在处理的代码;
  • 定义清楚干净代码和拙劣代码之间的边界,然后尝试把代码移过这条边界。

要点

  • 修改是程序一生都要面对的事情,,不仅包括最初的开发阶段,还包括首次发布之后;
  • 在修改中软件的质量要么该井,要么恶化。软件演化的首要法则就是代码演化应当提升程序的内在质量;
  • 重构成功之关键在于程序员应学会关注那些标志着代码需要重构的众多的警告;
  • 重构成功的另一要素是程序员应当掌握大量特定的重构方法;
  • 重构成功的最后要点在于要有安全的重构策略;
  • 开发阶段的重构是提升程序质量的最佳时机,因为你可以立刻让刚刚产生的改变梦想变成现实。

原文地址:https://www.cnblogs.com/liam-ji/p/11569082.html

时间: 2024-11-09 00:39:02

第二十四章 重构的相关文章

Gradle 1.12用户指南翻译——第二十四章. Groovy 插件

其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://github.com/msdx/gradledoc/tree/1.12. 直接浏览双语版的文档请访问: http://gradledoc.qiniudn.com/1.12/userguide/userguide.html. 另外,Android 手机用户可通过我写的一个程序浏览文档,带缓存功能的,兼容

第二十四章

希言自然.飘风不终朝,骤雨不终日.孰为此?天地,天地而弗能久,又况于人乎?故从事而道者同于道,德者同于德,失者同于失.同于德者,道亦德之.同于失者,道亦失之. 第二十四章1 为何盛世的领导者很少有丰功伟绩? 各位朋友大家好,今天我们接着来聊<道德经>.前边大家的留言我都看了,写的感想我也看了,我真的没想到大家感想写的这么好.而且这个<道德经>给大家带来这么多的变化.这么多的提升,让我特别开心,真的非常感动.我自己在讲<道德经>的过程中,说实话我自己也在不断地提升.也在学

【WPF学习】第二十四章 基于范围的控件

原文:[WPF学习]第二十四章 基于范围的控件 WPF提供了三个使用范围概念的控件.这些控件使用在特定最小值和最大值之间的数值.这些控件--ScrollBar.ProgressBar以及Slider--都继承自RangeBase类(该类又继承自Control类).尽管它们使用相同的抽象概念(范围),但工作方式却又很大的区别. 下表显示了RangeBase类定义的属性: 表 RangeBase类的属性 通常不比直接使用ScrollBar控件.更高级的ScrollViewer控件(封装了两个Scro

C#图解教程 第二十四章 反射和特性

反射和特性元数据和反射Type 类获取Type对象什么是特性应用特性预定义的保留的特性Obsolete(废弃)特性Conditional特性调用者信息特性DebuggerStepThrough 特性其他预定义特性有关应用特性的更多内容多个特性其他类型的目标全局特性自定义特性声明自定义特性使用特性的构造函数指定构造函数使用构造函数构造函数中的位置参数和命名参数限制特性的使用自定义特性的最佳实践访问特性使用IsDefined方法使用GetCustomAttributes方法 Note 类的元数据包含

第二十四章 C++11特性之右值引用

右值引用,是 C++11 语言核心中最为重要的改进之一.右值引用给 C++ 带来了“Move语义”(“转移语义”),同时解决了模板编程中完美转发的问题(Perfect forwarding).右值引用使 C++ 对象有能力甄别什么是(可以看作)临时对象,对于临时对象的拷贝可以做某种特别的处理,一般来说主要是直接传递资源的所有权而不是像一般地进行拷贝,这就是所谓的 move 语义了.完美转发则是指在模板编程的时候,各层级函数参数传递时不会丢失参数的“属性”(lvalue/rvalue, const

【读书笔记】C#高级编程 第二十四章 文件和注册表操作

(一)文件和注册表 对于文件系统操作,相关的类几乎都在System.IO名称空间中,而注册表操作由System.Win32名称空间中的类来处理. (二)管理文件系统 System.MarshalByRefObject--这是.NET类中用于远程操作的基对象类,它允许在应用程序域之间编组数据. FileSystemInfo--这是表示任何文件系统对象的基类. FileInfo和File--这些类表示文件系统上的文件. DirectoryInfo和Directory--这些类表示文件系统上的文件夹.

c++程序设计原理与实践 第二十四章部分答案

1 double f(double& d) 2 { 3 d*=2; 4 return d; 5 } 6 7 void f1(double&d) 8 { 9 d*=2; 10 } 11 12 double f2(double& d) 13 { 14 d*=2; 15 return d; 16 } 习题1 1 class f3{ 2 int i; 3 public: 4 f3(int i1):i(i1){} 5 //double operator()(double d){return

WP8.1学习系列(第二十四章)——Json解析

.net已经集成了json解析,类名叫DataContractJsonSerializer DataContractJsonSerializer 类型公开以下成员. 构造函数   名称 说明 DataContractJsonSerializer(Type) 初始化 DataContractJsonSerializer 类的新实例,以便序列化或反序列化指定类型的对象. DataContractJsonSerializer(Type, IEnumerable<Type>) 初始化 DataCont

老子《道德经》第二十四章

知其雄,守其雌,为天下溪. 为天下溪,常德不离,复归于婴儿. 知其白,守其黑,为天下式. 为天下式,常德不忒,复归于无极. 知其荣,守其辱,为天下谷. 为天下谷,常德乃足,复归于朴. 朴散则为器,圣人用之则为官长,故大制无割.