类级的重构

一、类实现的重构

  1.将值对象转化为引用对象:

    如果发现自己创建并维护着多个一模一样的大型复杂对象,请改变对这些对象的引用方式。

    即仅仅保存着一份主拷贝(值对象),然后其他地方使用对该对象的引用(引用对象)。

  2.将引用对象转化为值对象:

    如果看到自己对某个小型的简单对象进行了多次引用操作,请将这些对象都设置为值对象。

  3.用数据初始化替代虚函数:

    如果有一组派生类,差别仅仅是虚函数返回的常量不同。与其在派生类覆盖成员函数,不如

    让派生类在初始化时设定适当的常量值,然后使用基类中的通用代码处理这些值。

  4.改变成员函数或成员数据的位置:

    请考虑对类的继承体系做出修改。这些修改通常可以减少派生类的重复工作:

    1)将子程序上移到基类中。

    2)将成员上移到基类中。

    3)将构造函数的部分代码上移到基类中。

    4)对派生类进行特殊化,即下移到派生类中。    

  5.将特殊代码提取为派生类:

    如果某类里的一部分代码仅仅被其部分实例所使用,应该把这部分特殊的代码放到其派生类中。

  6.将相似的代码结合起来放置到基类中:

    如果两个派生类有相似的代码,将这些代码结合起来并放到基类中。

二、类接口的重构

  1.将成员函数放到另一个类中:

    在目标类中创建一个新的成员函数,然后从原类中将函数体移到目标类中,然后在旧的成员函数中调用新的成员函数。

  2.将一个类变成两个类

    如果一个类同时具备了两种或更多的截然不同的功能,请把这样的类转化为多个类,使得每个类完成一种明确定义的功能。

  3.删除类:

    如果某个类无所事事,就应该把该类的代码放到与所完成功能关系更为密切的另一个类中,然后把这个类删掉。

  4.去除委托关系:

    有时类A调用了类B和类C,而实际上类A只应该调用类B,而B类应该调用类C。在这种情况下就当考虑A对B的接口抽象

    是否合适。如果应该由B负责调用C,那么就应该只有B调用C。

  5.去掉中间人:

    如果存在类A调用类B,类B调用类C的情况,有时让类A直接调用类C会更好。是否应当去掉类B,取决于怎么做才能最好

    地维护类B接口的完整性。

  6.用委托代替继承:

    如果某类需要用到另一个类,但又打算获取对该类接口更多的控制权,那么可以让基类成为原派生类的一个成员,并公开它

    的一组成员函数,以完成一种内聚的抽象。

  7.用继承代替委托:

    如果某个类公开了委托类(成员类)所有的成员函数,那么该类应该从委托类继承而来,而不是使用该类。

  8.引入外部的成员函数:

    如果一个客户类需要被调用类的某个额外的成员函数,而你又无法去修改被调用类,那么可以通过在客户类中创建新成员函数

    方式来提供此功能。

  9.引入拓展类:

    如果一个类需要多个额外的成员函数,你同样无法修改该类,你可以创建一个新类。该类包括了原类的功能以及新增加的功能。

    要实现这点,你既可以通过从原类派生新类然后添加新的成员函数,也可以将原类进行包装,使新类调用所需要的成员函数。

  10.对暴露在外的成员变量进行封装:

    如果数据成员是公用的,请将其改为私用,然后通过成员函数来访问该数据成员的值。

  11.对于不能修改的类成员,删除相关的Set()成员函数:

    如果某个成员在对象创建之时被设值,之后便不能修改,那么就应该在对象的构造函数中对该成员初始化,而不是使用可能产生

    误导的Set()成员函数。

  12.隐藏那些不会在类之外被用到的成员函数:

    如果没有某个成员函数,类的接口更能呈现出内聚性,那就应该隐藏这个成员函数。

  13.封装不使用的成员函数:

    如果发现自己往往只使用类接口的一部分,那么就为类创建新的接口,仅仅把那些必须的成员函数暴露给类的外部。需要注意,

    新的接口应该为类提供一致的抽象。

  14.合并那些实现非常类似的基类和派生类:    

    如果派生类并未提供更多的特殊化,那么就应该把它合并回基类中。

时间: 2024-11-06 07:22:50

类级的重构的相关文章

python高级编程之(类级):子类内建类型

# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #类级 #在2.2中,提出了类型(type0与类(class)统一(请访问:https://www.python.org/download/releases/2.2.3/descintro(可能已经不存在了))-这使内建类型的子类化成为可能,并且添加一个新内建类型object #用于所有内建类的公共祖先 #展示一个名为distinctdict类的代码,与平常的dic

使用低版本Jackson 2的类级@JsonInclude包含策略的bug

本文出处:http://blog.csdn.net/chaijunkun/article/details/45110623,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议在原始出处查看此文. Jackson是Java语言中非常好用的对象与JSON相互转换的工具.然而本人的一次使用过程中发现了其老版本在某些情况下没有按照我们既定的序列化策略来生成JSON.本文将以使用过程中的例子来说明这一问题并给出相应的解决方法. 首先例子中要实现的功能是将对象转换为JSON时(序列

子程序级的重构

1.提取子程序或者方法: 把内嵌的代码从一个子程序中提取出来,并将其提炼为单独的子程序. 2.将子程序的代码内联化: 如果子程序的程序体很简单,且含义不言自明,那么就在使用的时候直接使用这些代码 3.将冗长的子程序转换为类: 如果子程序太长,可以将其转换为类,然后进一步对之前的子程序进行分解,通过所得到 的多个子程序来改善该代码的可读性. 4.用简单算法替代复杂算法: 用更为简单的算法来替代复杂的算法 5.增加参数 如果子程序需用从调用方获得更多的信息,可以增加它的参数从而为其提供信息. 6.删

数据级的重构

1.用具名常量替代神秘数值: 如果使用了数字或字符表示形式,例如3.14,那么请将这样的字符使用具名常量来替代,例如PI 2.使用变量的名字更为清晰且传递更多的信息: 如果一个变量的名字容易让人产生误解,就换个好点的名字 3.将表达式内联化: 把一个中间变量换成给它赋值的那个表达式本身 4.用函数来代替表达式: 用一个函数来代替表达式,这样一来表达式就不会在代码中重复出现 5.引入中间变量 将表达式的值赋给中间的变量,要记住,给这个中间变量的命名应能准确概况表达式的用途 6.用多个单一用途变量代

之前采用的是Helper类的方法重构时改用了扩展方法

在手机端输入网址不方全,通常会将网址做成一个二维码,然后用手机扫一下就可以打开预览.我们每改一下样式,就在手机上点一下刷新或电脑上按一下F5,这在最初的时候,也不觉得有什么问题,因为拿到我手上的静态页,通常由切片的同事做好了兼容性测试,需要一边刷新浏览器,一边改样式的机会不多.随着我们尝试用Less,stylus,这样的css工具,一方面,需要用到gulp这样的工具在后台自动监听我们的样式改动,另一方面,手动刷新的时候,gulp的脚本未必转换完了.这时候迫切需要浏览器自动刷新. 到此为止如果还没

语法最佳实践——低于类级之列表推导

python讲究python化,在列表推导时有两种常用的推导方式值得我们学习,因为它们能够使程序执行速度更快,避免检查.保存状态等行为. 第一种: 1 [i for i in range(10) if i % 2 == 0] 结果:[0, 2, 4, 6, 8] 第二种: seq = ['one', 'two', 'three'] for i, element in enumerate(seq): seq[i] = "%d: %s" % (i, seq[i]) print seq 结果

重构笔记——提炼类

本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43059759         在上一篇文章中介绍了"搬移字段".本文将介绍"提炼类"这种重构手法.         下面让我们来学习这种重构手法吧. 开门见山         发现:某个类做了应该由两个类做的事. 解决:建立一个新类,将相关的字段和函数从旧类搬移到新类. 动机 我们或多或少听过这样的教诲:一个类应该是一个清楚的

小酌重构系列[13]——移除中间类

我们有时候在应用程序中可能编写了一些"幽灵"类,"幽灵"类也叫中间类.这些中间类可能什么事儿都没做,而只是简单地调用了其他的组件.这些中间类没有发挥实际的作用,它们增加了应用程序的层级(layer),并且增加了应用程序的复杂性.这时,我们应将这样的中间类删除,甚至删除中间类所处的"中间层"--这就是本文要讲的重构策略"移除中间类". 移除中间类 图说 这个重构策略比较容易理解,下面这幅图演示了它的重构过程. 例外 通常情况下,

重构eclipse的新建Java类向页

插件项目中做一个弹出框通过类名包名新建Java类,就重构了下eclipse 新建Java向导类. 随便修改了下: 弹出代码: CustomNewClassCreationWizard wizard = new CustomNewClassCreationWizard(); wizard.init(PlatformUI.getWorkbench(), wizard.getSelection()); wizard.setForcePreviousAndNextButtons(true); MyWiz