【重构.改善既有代码的设计】7、在对象之间搬移特性(如何优化类)

7、在对象之间搬移特性

Move Method(搬移函数)

描述:
有个函数与其所驻class之外的另一个class进行更多交流:调用后者,或被后者调用。
在该函数最常引用(指涉)的class中建立一个有着类似行为的新函数。将旧函数变成一个单纯的委托函数(delegating method),或是将旧函数完全移除。

原因:
高耦合。依赖情节。

注意:
1、在迁移的时候,要考虑函数用到的属于原class的变量及其他函数,是否也应该迁移,这会是更大的收获。
2、不是所有变量都需要移动的,不能移动的作为调用参数也是可以的。

Move Field(搬移值域)

描述:
你的程序中,某个field(值域〕被其所驻class之外的另一个class更多地用到。
在target class 建立一个new field,修改source field的所有用户,令它们改用此new field。

Extract Class(提炼类)

某个class做了应该由两个classes做的事。
建立一个新class,将相关的值域和函数从旧class搬移到新class。

原因:
1、单一职责原则,一个变化只应该影响一个类,多种变化应该影响多个类。
2、改善并发,可以缩小锁的范围,精确锁的粒度。

使用场景:1、方法太多,2、变量太多。这样的class往往太大而不易理解。此时你需要考虑哪些部分可以分离出去,并将它们分离到一个单独的class中。

后续:
1、决定这个类要不要对外暴露?如果不暴露,可以采用委托方式。

Inline Class(将类内联化)

你的某个class没有做太多事情(没有承担足够责任)。
将class的所有特性搬移到另一个class中,然后移除原class。

与Extract Class 相反。

Hide Delegate(隐藏「委托关系」)

客户直接调用其server object(服务对象)的delegate class。

在server端(某个class〕建立客户所需的所有函数,用以隐藏委托关系(delegation)。

委托有好有坏,还是要根据情况决定是否要隐藏委托。

Remove Middle Man(移除中间人)

某个class做了过多的简单委托动作(simple delegation)。

让客户直接调用delegate(受托类)。

“Hide Delegate(隐藏「委托关系」)”的逆操作。

Introduce Foreign Method(引入外加函数)

你正在使用一个class,它真的很好,为你提供了你想要的所有服务。
而后,你又需要一项新服务,这个class却无法供应。
于是你开始咒骂:「为什么不能做这件事?」如果可以修改源码,你便可以自行添加一个新函数; 
如果不能,你就得在客户端编码,补足你要的那个函数。

其实就是把外面的方法装饰一下提供一个符合自己要求的新方法。

如果需要多个函数,或者多个类需要这个函数,那就用下一个方法:Introduce Local Extension(引入本地扩展)

Introduce Local Extension(引入本地扩展)

你所使用的server class需要一些额外函数,但你无法修改这个class。

建立一个新class,使它包含这些额外函数。让这个扩展品成为source class的subclass (子类〕或wrapper(外覆类)。

1、使用Subclass(子类)

这个容易的。继承后新加函数就好了。

2、使用wrapper(外覆类)

这种方案是在wrapper类中,聚合一个原始类,然后为原始类所有用到的函数提供委托函数。这个就会很烦。

原作者的总结

在对象的设计过程中,「决定把责任放在哪儿」即使不是最重要的事,也是最重要的事之一。
我使用对象技术已经十多年了,但还是不能一开始就保证做对。
这曾经让我很烦恼,但现在我知道,在这种情况下,我可以运用重构(refactoring),改变自己原先的设计。

常常我可以只运用 Move Method 和Move Field 简单地移动对象行为,就可以解决这些问题。
如果这两个重构手法都需要用到,我会首先使用Move Field,再使用Move Method。

class往往会因为承担过多责任而变得臃肿不堪。这种情况下,我会使用Extract Class 将一部分责任分离出去。
如果一个class变得太「不负责任」,我就会使用Inline Class 将它融入另一个class。
如果一个class使用了另一个class,运用Hide Delegate 将这种关系隐藏起来通常是有帮助的。
有时候隐藏delegate class会导致拥有者的接口经常变化,此时需要使用Remove Middle Man。

本章的最后两项重构——Introduce Foreign Method 和Introduce Local Extension ——比较特殊。
只有当我不能访问某个class的源码,却又想把其他责任移进这个不可修改的class时,我才会使用这两个重构手法。
如果我想加入的只是一或两个函数,我会使用Introduce Foreign Method;如果不止一两个函数,我就使用Introduce Local Extension。

我的总结

相对于第6章讲的是解决长函数的问题,本章讲的是不合理类的优化。

优化手段如下:
1、职责过多: 
1.1、包含了本属于其他类的函数:Move Method(搬移函数)
1.2、包含了本属于其他类的值:Move Field(搬移值域)
1.3、其他类还没有创建:Extract Class(提炼类)
2、职责过少:Inline Class(将类内联化)
3、聚合对象(中间人)接口过多/接口常变,维护困难:Remove Middle Man(移除中间人)
4、聚合对象(中间人)接口简单稳定,但访问多,需隐藏:Hide Delegate(隐藏「委托关系」)
5、少数sdk常用功能的扩展:Introduce Foreign Method(引入外加函数)
6、多数sdk常用功能的扩展:Introduce Local Extension(引入本地扩展)

原文地址:https://www.cnblogs.com/aoyihuashao/p/10383673.html

时间: 2024-11-05 18:35:18

【重构.改善既有代码的设计】7、在对象之间搬移特性(如何优化类)的相关文章

重构摘要7_在对象之间搬移特性

<重构-改善既有代码的设计>Martin Fowler 摘要: 第七章 在对象之间搬移特性 Move Method 搬移函数 你的程序中,有个函数与其所驻类之外的另一个类进行更多交流:调用后者,或被后者调用 在该函数最常引用的类中建立一个有着类似行为的新函数.将旧函数变成一个单纯的委托函数,或者将旧函数完全移除. Move Field 搬移字段 某个字段被其所驻类之外的另一个类更多地用到. 如果我需要对类做许多处理,保持小步前进是有帮助的. Extract Class 提炼类 某个类做了应该由

学习重构(3)-在对象之间搬移特性

1. Move Method(搬移函数) 在该函数最常用的勒种简历一个有着类似行为的新函数,将就函数变成一个单纯的委托函数,或是将就函数完全移除. 应用场景:搬移函数是重构理论的支柱,如果一个类有太多行为,或者一个类与另一个类有太多合作而形成高度耦合,我们就需要搬移函数.通过这种手段,我们可以使系统中的类更简单,这些类最终也将更干净利落的实现系统交付的任务. 示例: class A... void a1()... void a2() { B b = new B(); b.b1(); b.b2()

重构手法之在对象之间搬移特性【4】

返回总目录 本小节目录 Introduce Foreign Method(引入外加函数) Introduce Local Extension(引入本地扩展) 7Introduce Foreign Method(引入外加函数) 概要 你需要为提供服务的类增加一个函数,但你无法修改这个类. 在客户类中建立一个函数,并以第一参数形式传入一个服务类实例. 动机 好吧,我得不得说这个在C#中称为:扩展函数.这个其实也没什么好说的,这种事情发生过太多次了.假说你正在使用string类,它基本上提供了我们所需

《重构:改善既有代码的设计》(四) 第7章 在对象之间搬移特性

《重构-改善既有代码的设计》读书笔记

重构,第一个案例 1.1 起点 如果发现现有的代码结构使你无法很方便地添加新特性,那就先重构,使特性的添加比较容易进行后,再添加特性; 1.2 重构的第一步 为即将修改的代码建立可靠的测试环境 – 是人就会犯错,所以需要可靠的测试; 测试结果能够自我检验 – 成功"OK",失败列出失败清单并打印行号 (自动化对比测试结果是提高效率的前提); 1.3 分解并重组"巨型"函数 切分提炼长函数(Extract Method),并移至更合适的类(Move Method) –

《重构—改善既有代码的设计》笔记

为什么要重构 改进软件设计,消除重复代码 保持代码易读.易修改 提高编程速度(良好设计师维持软件开发速度的根本) 发现BUG 什么时候重构 事不过三,三则重构(三次法则) 添加功能时一并重构 修改错误时一并重构 复审代码时一并重构 问题代码 重复的代码 过长函数 过大类 过长参数列表 发散式变化 霰弹式修改 依恋情节 数据泥团 基本型别偏执 switch惊悚现身 冗赘类 夸夸其谈未来性 令人迷惑的暂时值域 过度耦合的消息链 中间转手人 狎昵关系 异曲同工的类 不完美的程序库类 纯稚的数据类 被拒

重构-----改善既有代码的设计

1重构原则 1.1 定义: 1).调整软件内部结构,目的是在不改变软件软件可查行为前提下,提高其可理解性,降低其修改成本. 2).使用一系列重构准则,在不改变软件可查行为前提下,调整其结构 1.2 何时重构 1).三次法则 2).添加功能时 3).修补错误时 4).复审代码时 1.3 何时不该重构 1).代码太乱,重构效率低于重写效率时 2).项目接近期限时停止重构 2.代码的坏味道 2.1 Duplicated Code 2.2 Long Method 2.3 Large Class 2.4

《重构--改善既有代码的设计》总结or读后感:重构是程序员的本能

此文写得有点晚,记得去年7月读完的这本书,只是那时没有写文章的意识,也无所谓总结了,现在稍微聊一下吧. 想起写这篇感想,还是前几天看了这么一篇文章 研究发现重构软件并不会改善代码质量 先从一个大家都有的经历说起吧. 刚开始学编程时,比如,要统计数字出现的次数,我们会这么定义变量 int i=0;//统计次数 老师看了说,代码要有可读性,见名知意; 于是,我们把它改成 int count=0; 后来才知道,原来这么一手这就是重构的第一式,重命名 (eclipse快捷键 alt+shift+R,最近

《重构——改善既有代码的设计》读书笔记

重构--改善既有代码的设计 1 重构概述 1.1 重构的概念(What) Refactoring 名词:对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低修改成本. 动词:使用一系列重构方法,在不改变软件可观察行为的前提下,调整其结构. 1.2 为什么要重构(Why) 改进软件设计 提高代码质量和可读性,使软件系统更易理解和维护 帮助尽早的发现缺陷 提高编程速度 1.3 何时重构(When) 何时重构: 1)随时随地进行. 2)三次法则:第一次做某件事只管去做: