重构和避免代码重复

Refactoring and avoiding code duplication

我 运行 遇到了一个新问题。基本上别人已经写了一个class A,重要的部分是这样的

class A{

 // some instance variables

 public A(){
  // Calls methods
  build();
  // Calls more methods
 }

 private build(){
  item = makeItem();
  anotherItem = makeAnotherItem();
  // more code
 }

 private makeItem(){
  // Does some things and calls updateItem()
 }

 private updateItem(){
  // Does some things with instance variables of class A
  // and calls yet another method in class A.
 }

我的问题是 build() 完全满足我的需要,但我在另一个 class 中需要它。现在的问题是:

  1. class A 比我写的要多得多,所以我不能创建它的对象。这将毫无意义。
  2. 我已经尝试为我的 class B 复制 build() 方法。但是,build() 使用其他方法。所以我也必须复制它们,当然它们会调用其他方法并使用在其他一些方法中声明的实例变量。基本上,我将不得不复制 200 行代码。

我猜这个问题实际上有一个名字,但我不知道它叫什么,因此只搜索了一些基本术语。如何在我的 class B 中使用 build()?

总是小步重构。例如把属于一起的东西放在一起,也许需要另一个 class C,它包含 makeItem、makeAnotherItem 和相应的实例变量。没有通用的答案,这取决于您的代码到底是什么样子

你在两个class中使用了构建方法的代码,但是继承没有用?然后你可以重用带有组合的构建方法的代码。 (提示Favor Composition over Inheritance)创建一个新的class C,其中包含构建方法。 class C 由 classes A 和 B 通过组合使用。他们委托给 class C 的构建方法。

参见 Martin Fowler 的重构方法。

https://sourcemaking.com/refactoring/smells/duplicate-code 另见 https://sourcemaking.com/refactoring/replace-inheritance-with-delegation

首先 如果 class A 中的 build() 正在使用 A 的其他私有方法,这听起来像是你需要 class A 本身.

一种选择是创建包含常用方法(包括构建方法)的抽象 class,并通过 class A 和 B 扩展此抽象 class。这样你不会有重复代码

如果出于某种原因你不想触摸 class A,我建议你创建一个像这样的界面:

public interface Builder{
    void build()
}

然后由你的 class B 实现这个接口,并且扩展 class A 这样你就可以实现构建方法。

public class B extends A implements Builder{
    // build() of class A will be used
    // do other staff
}

在这样做时,class A 根本没有变化(如果它是遗留代码或其他东西,这可能是需要的)+ Builder 可以用作 API 你的类型想暴露。