首页 > 代码库 > 代码的坏味道之二——译自《重构》

代码的坏味道之二——译自《重构》

巨型类

    当一个类尝试做的太多,它常常展示出过多的实例变量。当一个类有太多实例变量,重复代码的出现就不远了。

    你可以提取类来打包一部分变量。选择在部件中有意义的变量放在一起。例如,“存款总量”和“存款货币”很可能在同一部件中。更宽泛的说,在一个类中变量的某个子集共同的前缀和后缀预示着组成同一个部件的机会。如果这个部件有成为子类的意义,你会发现提取子类往往更容易。

    有时一个类不会一直使用它全部的实例变量。如果如此,你可能可以提取类或者提取子类若干次。

    相比于一个类有太多实例变量,一个类有太多代码是重复代码,混乱,死亡的黄金温床。最简单的解决方案是消灭类中的冗余。如果你有500行方法里面有很多相同的代码,你也许可以从原始代码里把他转变为5个10行的代码的方法还有10个两行代码 的方法。

    对于一个拥有大量填充变量的类,对有大量代码的类通常的解决方案都是提取类或提取子类。一个有用的技巧是判定客户怎么使用类来提取接口。这可能会给你进一步分解类提供想法。

    如果你的巨型类是GUI类,你可能需要将数据和行为移到分别的域对象。这可能需要在两边保留一部分重复数据并且保持数据同步。重复观察到的数据(Duplicate Observed Data)提示了怎么做。在这种情况下,尤其是如果你在用比较老的抽象窗口工具包(AWT)组件,你可能通过移除GUI类,替代以Swing组件。

 

长参数列表 

    在我们编程的早年里我们被教导传入所有需要的参数作为惯例。这很好理解,因为替代方式是全局数据,而全局数据是坏的并且常常很痛。对象改变了这一状况因为如果你有什么东西你需要的但是还没有,你总是可以向其他类要求去为你获取。这样有类对象你不需要传入方法需要的所有,取而代之你传入足够的这样方法可以获取它需要的所有。大多数方法需要的在方法的主类中可用。在面向对象编程里参数列表一般比传统的编程小的多。

    这很好,因为长参数列表难以理解,因为他们变得不一致并且难用,因为你永远会改变他们当你需要更多的数据时。大多数改变通过传入对象被移除,因为你更可能需要只是做几个请求来获取一片新数据。

    用通过方法替代参数重构方法,当你可以在一个参数中通过对你已知的对象做一些请求来获取数据。这个对象可能是一个域或者它可能是另一个参数。用保留整个对象来从一个对象获取一组数据然后用对象取代之。如果你有若干数据项不属于任何逻辑对象,用引入参数对象重构方法。

    对做这写改变有一个重要的例外。当你显式的不希望从调用方到更大的对象产生依赖。在这样的情况下,拆开数据,单独作为参数发送是理性的,但注意引入的痛。如果参数列表太长或者改变太频繁,你需要三思你的依赖架构。

 

发散的变化

    我们结构化我们的软件以使得改变更容易;毕竟,软件就应该软。当我们作改动的时候,我们希望我们可以跳到系统中一个清楚的点上来做改变。当你做不到这一点时,你在闻两个紧密相关的臭味之一。

    发散变化发生在一个类普遍的因不同原因有不同形式的改变。如果你看一个类,然后说."每当我有一个新数据库我需要改变这三个方法;每当有一个新的金融工具(financial instrument)的时候,我需要改变这四个方法," 你可能遇到了两个对象优于一个的时候。这样每个对象只因为一种改变而改变。当然,你常常只在你已经添加了几个心数据库或者金融工具时才会发现。任何处理变量的变化,应该只修改一个类,并且所有在新类打出的字应该表达那个变量。把这个清理干净,你需要鉴别所有改变特定分句的东西,然后用提取类把他们放在一起。