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

返回总目录

本小节目录

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

概要

你需要为提供服务的类增加一个函数,但你无法修改这个类。

在客户类中建立一个函数,并以第一参数形式传入一个服务类实例。

动机

好吧,我得不得说这个在C#中称为:扩展函数。这个其实也没什么好说的,这种事情发生过太多次了。假说你正在使用string类,它基本上提供了我们所需要的功能。但是,你正在做一项新服务,string类中恰巧无法提供。这时候你是不是想修改string的源代码,将这个功能加上。很可惜我们不能这么做,但是C#允许我们新建扩展函数。

范例

假如说,我们程序大量使用Dictionary<string,string>,我们要获得某个字典的value,可以这样做:

var dictionary = new Dictionary<string, string>();
string result;
dictionary.TryGetValue("key", out result);

但是我们每次都得定义一个out参数,这样很不方便。于是乎,我们建立一个扩展函数,至于怎么新建扩展函数,请自行百度。

public static class DictionaryExt
{
    public static string TryGetValue(this Dictionary<string, string> thisObj, string key)
    {
        if (thisObj == null || !thisObj.ContainsKey(key))
            return null;
        return thisObj[key] ?? "";
    }
}

这样一来,我们在使用的时候,就可以这样:

var dictionary = new Dictionary<string, string>();
var res = dictionary.TryGetValue("key");

这样一来大大提高了我们的效率。

小结

如果客户类只是用这项功能一次,那么额外编码工作没什么大不了,甚至可能根本不需要原本提供服务的那个类。然而,如果你需要多次使用这个函数,就得不断重复这些代码。

重复代码是软件万恶之源,重复代码应该被抽出来放进同一个函数中。

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

概要

你需要为提供服务的类提供一些额外函数,但你无法修改这个类。

建立一个新类,使它包含这些额外函数。让这个扩展品成为源类的子类。

动机

类的作者无法预知未来,他们常常没能为你预先准备一些有用的函数。如果只需要一两个函数,可以使用Introduce Foreign Method。但是如果需要的额外函数超过两个,外加函数就很难控制它们了。所以将这些函数组织在一起,让其成为源类的子类。这个子类称为本地扩展。

范例

我们还是以Dictionary<string,string>这个为例。

首先新建一个DictionaryString,让其成为Dictionary<string,string>的子类。

class DictionaryString : Dictionary<string, string>
{

}

然后在扩展类中添加新特性,并使用Move Method将所有外加函数搬移到扩展类。

class DictionaryString : Dictionary<string, string>
{
    public string TryGetValue(Dictionary<string, string> thisObj, string key)
    {
        if (thisObj == null || !thisObj.ContainsKey(key))
            return null;
        return thisObj[key] ?? "";
    }
    //other methods...
}

使用方法和上个手法一样:

DictionaryString dic=new DictionaryString();
dic.TryGetValue("key");

小结

使用本地扩展让我们坚持了“函数和数据应该被统一封装”的原则。如果一直把本该放在扩展类中的代码零散地放置于其他类中,最终只会让其他这些类变得过分复杂,并使得其中函数难以被复用。

阶段性小结

在对象的设计过程中,“决定把责任放在哪儿”即使不是最重要的事,也是最重要的事之一。我们可能一开始并不能保证自己做对。但是我们可以使用Move FieldMove Method简单地移动对象行为,就可以解决这些问题。

类往往会因为承担过多责任而变得臃肿不堪。这时候可以使用Extract Class将一部分责任分离出去。如果一个类变得太“不负责任”,就使用Inline Class将它融入另一个类。如果一个类使用了另一个类,运用Hide Delegate将这种关系隐藏起来。有时候隐藏委托类会导致拥有者的接口经常变化,此时需要使用Remove Middle Man

当不能访问某个类的源码,又想把责任移进这个不可修改的类时,要使用Introduce Foreign MethodIntroduce Local Extension。如果加入的是一或两个函数,就会使用Introduce Foreign Method;如果不止一两个函数,就要使用Introduce Local Extension

To Be Continued……

时间: 2024-10-06 11:10:58

重构手法之在对象之间搬移特性【4】的相关文章

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

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

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

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

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

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

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

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

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

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

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

重构笔记——搬移函数

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

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

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

重构笔记——搬移字段

本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42780243         在上一篇文章中介绍了"搬移函数".本文将介绍"搬移字段"这种重构手法.         下面让我们来学习这种重构手法吧. 开门见山         发现:程序中某个字段被其所驻类之外的另一个类更多地用到. 解决:在目标类新建一个字段,修改原字段的所有用户,令它们改用新字段. 动机 在类之间移动状态