重构定义:在不改变软件外部可观察行为的前提下,对软件内部结构的调整行为,提高代码的可读性,降低修改成本

1.一些感悟

  • 重构的目的实际上,就是为了使代码更容易理解和修改,什么是外部可观察行为,其实面向客户和其他程序员,功能和代码调用无改变,都不知道已经有东西发生了改变
  • 开发过程中,两顶帽子,一定不可以同时戴上,重构和新功能开发
  • 消除重复代码,是重构中经常做的事情,优秀设计的根本在于,将重复代码,归于一处,将不变抽离,将可变使用java的多态性,进行设计演变兼容
  • 重构使软件更容易理解,重构应该随时随地的进行,不应该为了重构而重构,你之所以重构,是因为想做的什么事情,重构可以帮你做的更好
  • 重构并不是修改错误代码,请谨记。重构时你总会发现某些代码并不正确。你绝对相信自己的判断,因此想马上把它们改正过来。啊,顶住诱惑,别那么做。重构时你的目标之一就是保持代码的功能完全不变,既不多也不少。对于那些需要修改的东西,列个清单把它们记录下来(通常我在计算器旁边放一张索引卡),需要添加或修改 的测试用例(test cases)、需要进行的其他重构、需要撰写的文档、需要画的图…… 都暂时记在卡上。这样就不会忘掉这些需要完成的工作。千万别让这些工作打乱你 手上的工作。重构完成之后,再去做这些事情不迟。

2.一些重构的方法

2.1 重新组织你的函数

1)Extract Method(提炼函数)
Extract Method是我最常用的重构手法之一。当我看见一个过长的函数或者一段需要注释才能让人理解用途的代码,我就会将这段代码放进一个独立函数中。
一个函数多长才算合适?在我看来,长度不是问题,关键在于函数名称和函数本体之间的语义距离。
使用此方法过程中,会发生临时变量的问题,那么此时根据实际情况(改变值?改变了对象?)来使用不同的手段,重构优化, Replace Temp with Query (以查询取代临时) or Remove Assignments to Parameters(移除对参数的赋值)
2)Inline Method(将函数内联化)
3)Replace Temp with Query(以查询取代临时变量)
4) Introduce Explaining Variable
5)Split Temporary Variable(剖解临时变量)
如果临时变量承担多个责任,它就应该被替换(剖 解)为多个临时变量,每个变量只承担一个责任。同一个临时变量承担两件不同的 事情,会令代码阅读者糊涂。
6)Remove Assignments to Parameters(移除对参数的赋值动作)
7)Replace Method with Method Object(以函数对象取代函数)
8)Substitute Algorithm(替换你的算法)

2.2 在对象之间搬移特性

1)Move Method(搬移函数)
2)Move Field
3)Extract class 某个class做了应该由两个classes做的事。
4)Inline Class(将类内联化)你的某个class没有做太多事情(没有承担足够责任)。
5)Hide Delegate(隐藏「委托关系」),很像代理,坏处显而易见,就是被代理的对象有新增行为时,代理类需要修改
6)Remove Middle Man(移除中间人),和上面的隐藏委托关系,相反
7)Introduce Foreign Method(引入外加函数),引入static函数
你所使用的server class需要一个额外函数,但你无法修改这个class。
8)Introduce Local Extension(引入本地扩展),继承或者装饰

2.3 重新组织数据

1) Self Encapsulate Field(自我封装),其实就是get、set
2) Replace Data Value with Object (用对象替换数据),将基本数据类型,封装为对象
3) Change Value to Reference (将实值对象改为引用对象)
将这个value object (实值对象)变成一个reference object (引用对象)
4) Replace Array with Object(用对象替换array)
5)Duplicate Observed Data(复制「被监视数据」),观察者模式
应该将处理用户界面(UI)和处理业务逻辑(business logic)的代码分开
6) Change Unidirectional Association to Bidirectional(将单向关联改为双向)
7) Change Bidirectional Association to Unidirectional(将双向关联改为单向)
8) Replace Magic Number with Symbolic Constant(以符号常量/字面常量取代魔法数)
9) Encapsulate Collection(封装群集)
10) Replace Type Code with Class(以类取代型别码)
switch语句中,根据类型,返回不同的对象,则可以将switch去除,通过模板设计模式,进行去除
11) Replace Subclass with Fields(以值域取代子类)

2.4 简化条件表达式

1)Decompose Conditional(分解条件式)
将if、else,进行函数抽离
2)Consolidate Conditional Expression(合并条件式)
将多个判断返回相同的代码,抽离为一种情况函数
3)Consolidate Duplicate Conditional Fragments(合并重复的条件片段)
将重复的条件判断,合并为一个函数
4)Remove Control Flag(移除控制标记)
以break 语句或return 的语句取代控制标记。
5)Replace Nested Conditional with Guard Clauses(以卫语句取代嵌套条件式)Hi
其实就是把多层嵌套语句,拆解为一个一个的简单判断函数,if else多层嵌套,那么拆解为多个单的if,然后再利用合并重复的条件判断,将其合并
6)Replace Conditional with Polymorphism(以多态取代条件式)
你手上有个条件式,它根据对象型别的不同而选择不同的行为。将这个条件式的每个分支放进一个subclass 内的覆写函数中,然后将原始函数声明为抽象函数(abstract method)。
7)Introduce Null Object(引入Null 对象)

2.5 简化函数调用

1)Rename method
2)Add parameter
3)Rmove parameter
4)Separate query from modifier(将修改和查询分离)
不要在一个函数中,既对一个对象修改,又返回,尽量让其只有一个功能
5)Preserve whole object(保持整个对象)
6)Introduce parameter object
7)Replace parameter with methods
8)Hide method
9)Replace construction with factory method
工厂模式,不应该用type来区别,这时应该想到反射+泛型的做法,因为这样的话,后续新增type,不必要再维护create函数
10)Encapsulate downcase(封装向下转型)
11)Replace error code with exception(以异常取代error code)

2.6 处理继承关系

1)Pull Up Field(值域上移)
2)Pull Up Method(函数上移)
其实两者都是指 subclass 与superclass 的函数与值域的相同提炼
3)Pull Up Constructor Body(构造函数本体上移)
其实就是在子类中,应该尽量使用super,而非自己完全重新创造
4)Push Down Method(函数下移)、Push Down Field(值域下移)
这两种情况出现的概率很小,父类中声明的方法或者值域,仅适用于某个子类,那么此时应该move
5)Extract Superclass(提炼超类)
6)Extract Interface(提炼接口)
7)Collapse Hierarchy(折叠继承关系),子类和父类并无多大区别,那么合并他们
8)Form Template Method(塑造模板函数)
两个子类中有相同的行为,但是他们又不是完全相同,那么此时可以抽离相同的部分,在父类中,形成模板函数
9)Replace Inheritance with Delegation(以委托取代继承)
某个subclass 只使用superclass 接口中的一部分,或是根本不需要继承而来的数据。
在subclass 中新建一个值域用以保存superclass ;调整subclass 函数,令它改而委托superclass ;然后去掉两者之间的继承关系。
10)Replace Delegation with Inheritance(以继承取代委托)
这个其实挺不建议的, 可以通过 Remove Middle Man 让客户端自己调用受托函数,也可以使用Extract Superclass 将两个classes 接口相同的部分提炼到superclass 中, 然后让两个classes 都继承这个新的superclass ;你还可以以类似手法使用Extract Interface。

3.总结

永远不要忘记「两顶帽子」重构与开发是两顶帽子,要时常交换进行,不可以同时戴上。

关于重构的原则和思想总结相关推荐

  1. 设计原则与思想:规范和重构(11讲)

    文章目录 设计原则与思想:规范和重构(11讲) 理论一:什么情况下要重构?到底重构什么?又该如何重构? 重构的目的:为什么要重构(why)? 重构的对象:到底重构什么(what)? 重构的时机:什么时 ...

  2. 设计原则与思想:设计原则12讲

    文章目录 设计原则与思想:设计原则(12讲) 理论一:对于单一职责原则,如何判定某个类的职责是否够"单一"? 如何理解单一职责原则(SRP)? 如何判断类的职责是否足够单一? 类的 ...

  3. 【设计模式之美 设计原则与思想:设计原则】22 | 理论八:如何用迪米特法则(LOD)实现“高内聚、松耦合”?

    今天,我们讲最后一个设计原则:迪米特法则.尽管它不像 SOLID.KISS.DRY 原则那样,人尽皆知,但它却非常实用.利用这个原则,能够帮我们实现代码的"高内聚.松耦合".今天, ...

  4. 【重构篇js案例解析重构】第一章 重构的原则

    重构的原则 重构代码示例 重构前的代码 var plays = {"hamlet": { "name": "Hamlet", "t ...

  5. 设计原则与思想:面向对象11讲

    文章目录 设计原则与思想:面向对象11讲 理论一:面向对象到底是什么 面向对象编程和面向对象编程语言? 如何判定某编程语言是否是面向对象编程语言? 什么是面向对象分析和面向对象设计? 理论二:封装.抽 ...

  6. 【软件架构】软件架构设计常用概念、原则与思想

    导读 本文一文总结软件架构设计常用概念.原则与思想,包括面向对象六大原则,DID原则,ACID.CAP.BASE理论,中间层思想,缓存思想等. 软件架构设计常用概念.原则与思想 面向对象设计六大原则 ...

  7. 【设计模式之美 设计原则与思想:设计原则】23 | 实战一(上):针对业务系统的开发,如何做需求分析和设计?

    对于一个工程师来说,如果要追求长远发展,你就不能一直只把自己放在执行者的角色,不能只是一个代码实现者,你还要有独立负责一个系统的能力,能端到端(end to end)开发一个完整的系统.这其中的工作就 ...

  8. 【重构】一、重构的原则

    重构的原则 文章目录 重构的原则 0 什么是重构 两顶帽子 为什么要重构 重构改进软件的设计 重构使软件更容易理解 重构能帮助找到bug 重构提高编程速度 什么时候重构 预备性重构:让添加新功能更容易 ...

  9. 设计原则与思想【面向对象、设计原则、编程规范、重构技巧】

    一.高质量代码的评判标准: 可维护性:在不破化原有代码设计.不引入新的bug的情况下,能够快速的修改或者添加代码 可读性:我们需要看代码是否符合编码规范.命名是否达意.注释是否详尽.函数是否长短合适. ...

最新文章

  1. httpd启动不能加载模块
  2. 如何加快Simulink模型的仿真速度
  3. SAP Analytics Cloud里Exception Aggregation Type的设置
  4. python类成员变量_Python 类变量和成员变量
  5. mysql hdfs_MySQL数据库与HDFS的实时数据同步
  6. ResourceExhaustedError 解决方案
  7. oracle 存储过程详细介绍(创建,删除存储过程,参数传递等)1
  8. 大数据可视化平台Demo
  9. A/B Test(AB测试) 流程、常见面试问题及解答
  10. java:布局方法(边界布局)
  11. java基础第十五篇之IO流和递归算法
  12. 学习C的知识点扩展2--make和makefile多文件编译的使用
  13. 大白话之哈希表和哈希算法
  14. Java图片缩略图裁剪水印缩放旋转压缩转格式-Thumbnailator图像处理
  15. 用python替换文件中内容的方法
  16. 【汤普森问题】正弦定理乱搞解法
  17. Win11文件夹拒绝访问怎么办?
  18. 专访罗升阳:老罗的Android之旅(转载)
  19. C语言电子闹钟(显示时间、计时器、闹钟、倒计时、世界时钟)C语言大作业
  20. A Blockchain-Based Nonrepudiation Network Computing Service Scheme for Industrial IoT 阅读笔记

热门文章

  1. 使用神经网络进行皮肤癌的诊断
  2. Flash中打开链接绕过弹出窗口阻拦程序的方法
  3. 电脑颜色 (视力保护的最佳选择) 什么颜色对眼睛最好?
  4. talk additionally North Face Jassen will not
  5. Nginx 清除缓存配置
  6. Windows10自带手机投屏功能
  7. C#委托和事件 EventHandle和EventArgs
  8. Vmware虚拟机网络模式原理及配置详解
  9. 搜索与回溯算法之—自然数的拆分
  10. 前端连接后端,获取到数据库数据,通过ECharts图标展现在页面上