解决方案:创建与条件的分支相匹配的子类。在它们中,创建一个共享方法,并将代码从条件的相应分支移动到它。然后用相关的方法调用替换条件。结果是,根据对象类,可以通过多态实现正确的实现。
引入空对象
问题:由于一些方法返回null而不是真实对象,所以在代码中有很多null检查。
解决方案:返回一个显示默认行为的空对象,而不是null。
引入断言
问题:要使部分代码正常工作,某些条件或值必须为true。
解决方案:用特定的断言检查替换这些假设。
简化方法调用这些技术使方法调用更简单、更容易理解。这反过来简化了用于类之间交互的接口。
重命名方法
问题:方法的名称不能解释该方法的功能。
解决方案:重命名该方法。
添加参数
问题:方法没有足够的数据来执行某些操作。
解决方案:创建一个新参数来传递必要的数据。
删除参数
问题:方法体中没有使用某个参数。
解决方案:删除未使用的参数。
将查询与修改分开
问题:是否有一个方法可以返回一个值,但也可以更改对象内部的某些内容?
解决方案:将该方法分为两种不同的方法。正如你所料,其中一个应该返回值,另一个则修改对象。
将方法参数化
问题:多个方法执行类似的操作,这些操作只在其内部值、数字或操作上有所不同。
解决方案:通过使用一个将传递必要特殊值的参数来组合这些方法。
用显式方法替换参数
问题:一个方法被分成几个部分,每个部分的运行取决于一个参数的值。
解决方案:将方法的各个部分提取到它们自己的方法中,并调用它们,而不是原始方法。
保存整个对象
问题:从一个对象中获取多个值,然后将它们作为参数传递给一个方法。
解决方案:相反,尝试传递整个对象。
用方法调用替换参数
问题:调用一个查询方法并将其结果作为参数传递给另一个方法,而该方法可以直接调用该查询。
解决方案:不要通过参数传递值,而是尝试在方法体中放置一个查询调用。
引入参数对象
问题:你的方法包含一组重复的参数。
解决方案:用对象替换这些参数。
移除设置方法
问题:字段的值应该只在创建时设置,之后任何时候都不能更改。
解决方案:删除设置字段值的方法。
隐藏方法
问题:一个方法不被其他类使用,或者只在它自己的类层次结构中使用。
解决方案:将方法设置为私有或受保护。
用工厂方法代替构造器
问题:你有一个复杂的构造器,它的功能不仅仅是在对象字段中设置参数值。
解决方案:创建一个工厂方法并使用它替换构造器调用。
用异常替换错误代码
问题:方法返回指示错误的特殊值?
解决方案:抛出一个异常。
用测试替换异常
问题:在一个简单的测试就能完成任务的地方抛出异常?
解决方案:用条件测试替换异常。
处理泛化抽象有自己的一组重构技术,主要关于沿着类继承层次结构移动功能、创建新的类和接口、用委托代替继承以及相反。
上移字段
问题:两个类具有相同的字段。
解决方案:从子类中删除字段,并将其移动到超类。
上移方法
问题:你的子类具有执行类似工作的方法。
解决方案:使方法相同,然后将它们移动到相关的超类。
上移构造器主体
问题:你的子类的构造器的代码基本相同。
解决方案:创建一个超类构造器,并将子类中相同的代码移动到它。在子类构造器中调用超类构造器。
下移方法
问题:超类中实现的行为是仅由一个(或几个)子类使用的吗?
解决方案:将此行为移动到子类。
下移字段
问题:字段是否仅用于少数子类?
解决方案:将字段移动到这些子类。
提取子类
问题:某个类具有仅在某些情况下使用的功能。
解决方案:创建一个子类,并在这些情况下使用它。
提取超类
问题:有两个类具有相同的字段和方法。
解决方案:为它们创建一个共享超类,并将所有相同的字段和方法移动到其中。
提取接口
问题:多个客户端使用类接口的同一部分。另一种情况:两个类中的部分接口是相同的。
解决方案:将这个相同的部分移动到它自己的接口。
折叠层次结构
问题:你有一个类层次结构,其中一个子类实际上与其超类相同。
解决方案:合并子类和超类。
形成模板方法
问题:你的子类实现的算法包含顺序相同的类似步骤。
解决方案:将算法结构和相同的步骤移动到一个超类,并将不同步骤的实现留在子类中。
用委托替换继承
问题:有一个子类只使用其超类的一部分方法(或者不可能继承超类数据)。
解决方案:创建一个字段并在其中放置一个超类对象,将方法委托给超类对象,并摆脱继承。
用继承替换委托
问题:一个类包含许多简单的方法,这些方法将委托给另一个类的所有方法。
解决方案:使该类继承另一个类,这样就不需要委托方法。