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

1. Move Method(搬移函数)

在该函数最常用的勒种简历一个有着类似行为的新函数,将就函数变成一个单纯的委托函数,或是将就函数完全移除。

应用场景:搬移函数是重构理论的支柱,如果一个类有太多行为,或者一个类与另一个类有太多合作而形成高度耦合,我们就需要搬移函数。通过这种手段,我们可以使系统中的类更简单,这些类最终也将更干净利落的实现系统交付的任务。

示例:

class A...

void a1()...

void a2() {

B b = new B();

b.b1();

b.b2();

}

class B...

void b1()...

void b2()...

重构为:

class A...

void a2() {

B b = new B();

b.b3();

b.b2();

b.a1();

}

class B...

void b1()...

void b2()...

void a1()...

2. Move Field(搬移值域)

在目标类新建一个字段,修改元字段的所有用户,令他们改用新字段。

应用场景:在类之间移动状态和行为,是重构过程中必不可少的措施。随着系统发展,你会发现自己需要新的类,并需要将原本的工作职责拖到新的类中,当前合理而正确的设计决策,在未来可能不在正确,这没问题,如果你从来没遇到过这种情况,那才有问题。

示例:

class A...

private int id;

private String name;

class B...

private String name;

重构为:

class A...

private String name;

class B...

private int id;

private String name;

3.Extract Class(提炼类)

建立一个新类,将相关的字段和函数从旧类搬移到新类

应用场景:你也许听过类似的教诲:一个类应该是一个清楚的抽象,处理一些明确的责任。但是实际工作中,类会不断成长扩张,你会在这加入一些功能,在那加入一些数据。给某个类添加一项新责任时,你会觉得不值得为这项新责任分离出一个单独的类。于是,随着责任不断增加,这个类变得过分复杂,成为一团乱麻。这样的类往往含有大量函数和数据,因为太大而不易理解。此时需要考虑将哪些部分可以分离出去,放到一个单独的类中。如果某些数据和某些方法总是一起出现,如果某些数据经常同时变化甚至彼此相依,这就表示它们应该被分离出去。

示例:

class Team...

private String engineer1;

private String engineer2;

private String tester1;

private String tester2;

重构为:

class Team...

Engineer engineerTeam;

Tester testerTeam;

class Engineer ...

private String engineer1;

private String engineer2;

class Tester...

private String tester1;

private String tester2;

4. Inline Class(将类内联化)

将这个类的所有特性搬移到另一个类种,然后移除原类。

应用场景:如果一个类不在承担足够的责任,不在有单独存在的理由(这通常是因为此前的重构动作移走了这个类的责任),此时就需要将这个萎缩类塞到其他的类中。

示例:

class Person...

private String name;

private Telephone telephone;

class Telephone...

private String areaCode;

private String number;

String getTelephoneNumber()...

重构为:

class Person...

private String name;

private String areaCode;

private String number;

String getTelephoneNumber()...

5. Hide Delegate(隐藏“委托关系”)

在服务类上建立客户所有的所有函数,用以隐藏委托关系。

应用场景:这个核心思想就是封装。如果某个客户调用了建立与服务对象某个值域基础之上的函数,那么客户就必须维护这层关系,一旦这层委托关系发生变化,比如此服务对象的值域有变化,那么客户也要去响应这个变化才能继续使用原来的函数。我们可以在服务端防止一个简单的委托函数,将这层委托关系隐藏起来,从而去除这个一寸性。这样即使将来委托关系发生变化,变化会被限定在服务端,客户不会受到影响。

示例:

class Client...

void func1() {

Person p = new Person();

String manager = p.getDepartment().getManager();

class Person...

Department getDepartment();

class Department...

String getManager();

重构为:

void func1() {

Person p = new Person();

String manager = p.getManager();

class Person...

Department getDepartment();

String getManager() {

return getDepartment().getManager();

}

class Department...

String getManager();

6. Remove Middle Man (移除中间人)

让客户直接调用委托类。

应用场景:与 第5条Hide Delegate(隐藏“委托关系”)正好相反,隐藏“委托关系”的代价是每当客户要使用受委托类的新特性时,就必须在服务端添加一个简单的委托函数,随着特性越来越多,带来的代价不断攀升。所以两种方法存在一个折中的关系,说不上绝对要使用哪一种,结合实际情况合理决策。

示例:

void func1() {

Person p = new Person();

String manager = p.getManager();

class Person...

Department getDepartment();

String getManager() {

return getDepartment().getManager();

}

class Department...

String getManager();

重构为:

class Client...

void func1() {

Person p = new Person();

String manager = p.getDepartment().getManager();

class Person...

Department getDepartment();

class Department...

String getManager();

7. Introduce Foreign Method(引入外加函数)

在client class中建立一个函数,兵役一个server class实体作为第一引数。

应用场景:当我们正在使用一个类,它为我们提供了想要的所有服务,突然有一天,我们需要一个新功能,但是这个类无法提供,如果可以修改源码,那么万事大吉,否则我们就只能在调用的地方去补齐我们的功能。如果只使用一次这个功能,那么额外编码工作没什么大不了,然后如果需要多次使用这个函数,就得不断重复这些代码。重复代码是软件万恶之源,这些重复代码应该被抽出来放进同一个函数中。进行本项重构时,如果以外加函数实现一项功能,那就是一个明确信号:这个函数原本应该在提供服务的类中加以实现。如果需要大量外加函数,那么这种方法就不建议使用了。外加函数终归是权宜之计,如果有可能,应该把这些函数放到他们的理想家园。

示例:

Date newStart = new Date(previousEnd.getYear(), previousEnd.getMonth(), previousEnd.getDate()+1);

重构为:

Date newStart = nextDay(previousEnd);

private static Date nextDay(Date date) {

return new Date(date.getYear(), date.getMonth(), date.getDate()+1);

8. Introduce Local Extension(引入本地扩展)

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

应用场景:类的作者无法预知未来,他们提供的函数可能不够用,如果我们可以修改源码,那么就可以很容易的增加或者修改已有类来满足使用;或者我们调用的地方少,增加的函数少时,可以使用第7条(Introduce Foreign Method(引入外加函数))来满足诉求。为了解决这个问题,我们需要将这些函数组织到一起,放到一个恰当的地方,此时,标准对象技术subclassing和wrapping是不错的选择。两种方法做选择时,首选subclass,这样的工作量比较少。

subclass或wrapper示例:

class SubDate extends Date {

....

class DateWrapper {

private Date _date;

}

原文地址:https://www.cnblogs.com/youknowzcm/p/11729337.html

时间: 2024-10-14 17:45:21

学习重构(3)-在对象之间搬移特性的相关文章

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

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

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

7.在对象之间搬移特性 Move Method(搬移函数) 描述:有个函数与其所驻class之外的另一个class进行更多交流:调用后者,或被后者调用.在该函数最常引用(指涉)的class中建立一个有着类似行为的新函数.将旧函数变成一个单纯的委托函数(delegating method),或是将旧函数完全移除. 原因:高耦合.依赖情节. 注意:1.在迁移的时候,要考虑函数用到的属于原class的变量及其他函数,是否也应该迁移,这会是更大的收获.2.不是所有变量都需要移动的,不能移动的作为调用参数

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

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

第3章 在对象之间搬移特性(2):提炼类、类的内联化

3. 提炼类(Extract Class) 3.1 动机 (1)某个类做了应该由两个类做的事,可以将相关字段和函数从旧类搬移到新类. (2)当某些特性需要以一种方式来子类化,另外一些特性则需要以另一种方式子类化,这就意味着需要分解原来的类. 3.2 做法 (1)决定如何分解类所负的责任. (2)建立一个新类,用以表现从旧类中分离出来的责任.如果旧剩下的责任与旧类名称不符,也可以为旧类更名. (3)建立“从旧类访问新类”的连接关系.有时可能需要一个双向连接,但是在真正需要它之前,不要建新“从新类通

在对象之间搬移特性---Hide Delegate(隐藏委托关系)

客户通过一个委托类来调用另一个对象. 在服务类上建立客户所需的所有函数,用以隐藏委托关系. 动机: 封装即使不是对象的最关机特性,也是最关机特性之一."封装"意味着每个对象都应该少了解系统的其他部分.如此以来,一旦发生变化,需要了解这一变化的就比较少---这会使系统比较容易进行. 任何学过对象技术的人都知道:虽然Java将字段声明为public,但你还是应该隐藏对象的字段.随着经验日渐丰富,你会发现,有更多可以(值得)封装的东西. 如果某个客户需要通过服务对象的字段得到另一个对象,然后

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

学习重构(0)-目录

何时重构 如何重构 代码坏味道 Duplicated Code(重复代码) 重新组织函数 Extract Method(提炼函数) Long Method(过长函数) Inline Method(内联函数) Large Class(过大的类) Inline Temp(内联临时变量) Long Parameter List(过长参数列) Replace Temp with Query(以查询取代临时变量) Divergent Change(发散式变化) Introduce Explaining V

重构笔记——搬移函数

本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42679983         我们都知道,类往往因为承担过多的责任而变得臃肿不堪.这种情况下,一般会使用"提炼类"这种手法将一部分责任分离出去.如果一个类变得"不负责任",一般会使用"内联类"这种手法将它融入另一个类.如果一个类使用了另一个类,一般会运用"隐藏委托关系"手法将这种关系隐藏

【Java重构系列】重构31式之搬移方法

重构第二式:搬移方法 (Refactoring 2: Move Method) 毋容置疑,搬移方法(Move Method)应该是最常用的重构手段之一,正因为太常用而且较为简单,以至于很多人并不认为它是一种很有价值的重构,但事实并非如此,在最初的代码诞生之后,有些方法可能会被放在一些不合适的地方,例如,一个方法被其他类使用比在它所在的类中的使用还要频繁或者一个方法本身就不应该放在某个类中时,我们应该考虑将它移到更合适的地方.搬移方法,顾名思义就是将方法搬移至合适的位置,如将方法搬移到更频繁地使用