美文网首页《重构》读书笔记
《重构》学习笔记(10)-- 重构的实战

《重构》学习笔记(10)-- 重构的实战

作者: 若隐爱读书 | 来源:发表于2019-10-21 22:58 被阅读0次

梳理并分解继承体系

某个继承体系同时承担两项责任,那么就建立两个继承体系,并通过委托关系让其中一个可以调用另一个。


重构前

梳理后,重构为:


重构后
做法:
  • 首先识别出继承体系所承担的不同责任,然后建立一个二维表格(或者三维表格乃至四维表格,。。),并以坐标轴标示出不同的任务,我们将重复利用此重构,处理两个或者两个以上的重构(每次只处理一个维度)。
  • 判断哪一项重构更重要,并准备将它留在当前继承体系中,准备将另一项责任移到另一个继承体系。
  • 使用Extract Class 从当前的超类提炼出一个新类,用以表示重要性稍低的责任并在源超类中添加一个示例变量,用以保存新类的实例。
  • 对应于原继承体系中的每个子类,对应的创建上述新建的一个子类,在源继承体系的子类中,将前一步所添加的实例变量初始化为新建子类实例。
  • 针对原继承体系的每个子类,使用Move Method 将其中的行为搬移到与之对应的新建子类中。
  • 当源继承体系中的某个子类不再具有任何代码时,就去除它。
  • 重复上述步骤,直到源继承体系中所有子类都被处理为止,观察新继承体系,看看是否可能对它实施重构手法【继承体系重构手法】。

Convert Procedural Design to Objects(将过程化设计转化为对象设计)

有一些传统过程化风格的代码,将数据记录变成对象,将大块的行为分成小块,并将行为移入相关的对象中


重构前
重构后

做法

  • 针对每一个记录类型,将其转化成只含有访问原函数的啞数据对象
    如果你的数据来自关系型数据库,就把数据库中的每一个表变成啞数据对像
  • 针对每一处过程化风格,将该处的代码提炼到一个独立函数
    可以把提炼的类做成一个Singleton(为了方便重新初始化),或提炼所得的函数声明为static
  • 针对每一段长长的程序,实施Extract Method及其他相关的重构将它分解,在以Move Method将分解后的函数移动到相关的啞对象中
  • 重复上述步骤,直到原始类的所有函数都被移除,如果原始类是一个过程化类,一定要移除。

Separate Domain from Presentation(将业务/领域和表述/显示分离)

某些GUI类之中包含了领域逻辑。将领域逻辑分离出来,为他们建立独立的领域类.


重构前
重构后

做法

  • 为每一个窗口建立一个领域类.
  • 如果窗口内有一张表格,新建一个类来表示其中的性=行,再以窗口所对应之领域类中的一个集合来容纳所有的行领域对象
  • 检查窗口中的数据,如果数据只被用于UI,就把它留着;如果数据被领域逻辑使用,而且不显示于窗口上,我们就以Move Field将它搬移到领域类中;如果数据同时被UI和领域类使用,就对他实施Duplicate Obsersed Data,使它同时存在于两处,并保持两处之间的同步。
  • 检查展现类中的逻辑,实施Extract Method将展现逻辑从领域逻辑中分开,一旦隔离了领域逻辑,在运用Move Method 将它移动到领域类
  • 以上步骤完成之后,你就拥有了两组类.

Extract Hierarchy(提炼继承体系)

你有某个类做了太多工作,其中一部分工作是以大量条件表达式完成的。
建立继承体系,以一个子类来表示一种特殊情况。


重构前
重构后

在渐进式设计过程中,常常会有这样的情况:一开始设计者只想以一个类实现一个概念;但随着设计方案的演化,最后却可能一个类实现了两个、三个乃至十个不同的概念。一开始,你建立了这个简单的类。数天或数周之后,你可能发现:只要加入一个标记和一两个测试,就可以在另一个环境下使用这个类;一个月之后你又发现了另一个这样的机会;一年之后,这个类就完全一团糟了:标记变得和条件表达式遍布各处。

当你遇到这种瑞士军刀般的类--不但能够开瓶开罐、砍小树枝、还能在演示会上打出激光强调重点--你就需要一个好策略(亦如本项重构),将它的各个功能梳理并分开。不过,请注意,只有当条件逻辑在对象的整个生命周期保持不变,本重构导入的策略才适用。否则你可能必须在分离各种状况之前先使用Extract Class

Extract Hierarchy 是一项大型重构,如果你一天之内不足以完成它,不要因此失去勇气。将一个极度混乱的设计方案梳理出来,可能需要数周甚至数月的时间。你可以先进行本项重构中的一些简易步骤,稍微休息一下,再花几天时间编写一些能体现产出的代码。当你领悟到更多东西,再回来继续本项重构的其他步骤--这些步骤将因为你的领悟而显得更加简单明了。

做法
我们为你准备了两组重构手法。第一种情况是:你无法确定哪些地方会发生变化。这时候你会希望每次一小步地前进。

  • 鉴别出一种变化情况。
    如果这种变化可能在对象声明周期的不同阶段而有不同体现,就运用Extract Class 将它提炼为一个独立的类。
  • 针对这种变化情况,新建一个子类,并对原始类实施Replace Constructor with Factory Method。再修改工厂函数,令它返回适当的子类实例。
  • 将含有条件逻辑的函数,一次一个,逐一复制到子类,然后在明确情况下(对子类明确,对超类不明确),简化这些函数。
    如有必要隔离函数中的条件逻辑和非条件逻辑,可对超类实施Extract Method.
  • 重复上述过程,将所有变化情况都分离出来,直到可以将超类声明为抽象类为止。
  • 删除超类中那些被所有子类覆写的函数本体,并将它们声明为抽象函数。

如果你非常清楚原始类会有哪些变化情况,可以使用另一种做法。

  • 针对原始类的每一种变化情况,建立一个子类。
  • 使用Replace Constructor with Factory Method将原始类的构造函数转变成工厂函数,并令它对每一种变化返回适当的子类实例。
    如果原始类中的各种变化情况是以类型码表示,先使用Replace Type Code with Subclass;如果那些变化情况在对象生命周期的不同阶段会有不同体现,请使用Replace Type Code with State/Strategy。
  • 针对带有条件逻辑的函数,实施Replace Conditional with Polymorphism 。如果并非整个函数的行为有所变化,而只是函数一部分有所变化,请先运用Extract Method将变化部分和不变部分分隔开来。

相关文章

  • 《重构》学习笔记(10)-- 重构的实战

    梳理并分解继承体系 某个继承体系同时承担两项责任,那么就建立两个继承体系,并通过委托关系让其中一个可以调用另一个。...

  • 读书笔记

    《系统之美》 《重构》 《Redis 实战》 《Effective Java》 《Spring Boot实战》 《...

  • 重构:读书笔记

    重构读书笔记 第一章 重构,第一个案例 第二章 重构原则 2.1 何为重构 重构(名词):对软件内部结构的一种调整...

  • 改善既有代码的设计笔记(三)代码的坏味道

    前面两篇笔记涉及到了部分重构的时机,本篇笔记全部为重构代码的时机。重构时机,不是僵硬死板的必须在什么时候执行,下面...

  • 如何实施代码重构?

    阅读《重构》的笔记献上。 重构的定义 重构是在不改变软件可观察行为的前提下改善其内部结构。 重构的节奏 以微小的步...

  • 《重构》学习笔记

    最近在读《重构》这本书,试着把书中对我启发较大的一些点记录下来,以便回顾学习。 一、replace temp wi...

  • 我的Android重构之旅:架构篇

    我的Android重构之旅:架构篇我的Android重构之旅:框架篇我的Android重构之旅:插件化篇 去年10...

  • 代码重构专题(转载)

    代码重构(一):函数重构规则代码重构(二):类重构规则代码重构(三):数据重构规则代码重构(四):条件表达式重构规...

  • 《重构》学习笔记(01)--什么是重构

    什么是重构? 所谓重构是这样一个过程:在不改变代码外在行为的前提下,对代码作出修改,以改进程序的内部结构。本质上说...

  • 重构代码之美

    什么是重构; 为什么要重构; 什么时候重构; 怎样避免重构的现象; 重构的难点在哪里; 如何来实施代码重构; 重构...

网友评论

    本文标题:《重构》学习笔记(10)-- 重构的实战

    本文链接:https://www.haomeiwen.com/subject/fawxvctx.html