10

我试图通过将一个类分解为其他几个类来重构一些代码。为此,我想将旧类中已经存在的一些方法移至新类。但是这些方法在很多地方都被引用,手动更新引用似乎很烦人。那么有什么方法可以移动方法并在 eclipse 中更新它们的引用?

4

6 回答 6

10

我会这样做:

  1. 确保您的测试正常工作,并且覆盖了要重构的代码。如果您没有测试,请编写测试。它们是你的安全绳。
  2. 使用重构模式提取超类来创建您想要将一些方法移动到的新类。
  3. 使用重构模式pull up 方法将方法连同它们需要的变量一起移动到超类。现在您将看到您想要移动的方法和实例变量是否依赖于您不想移动的其他方法。如果是这样,您必须首先打破这种依赖关系。
  4. 找到所有应该使用新提取的类而不是“旧”类的客户端代码,并将其重写为新提取的类。
  5. 删除两个类之间的“扩展”关系。现在客户端代码应该可以工作,否则你错过了一些东西。

另外一本学习如何应用重构模式的好书是有效地使用遗留代码

于 2013-11-15T06:52:28.823 回答
3

如果您使用 Eclipse IDE,那么重构将对您有所帮助。

在此处输入图像描述

于 2013-11-15T06:46:51.047 回答
2

我将向您展示我遵循的过程。考虑这样的代码:

public class GodClass {
    public someInstanceMethodToMove() {
         // some code 1
    }

    public static someStaticMethodToMove() {
         // some code 2
    }

    public static void main(String[] args) {
        GodClass c = ...;
        c.someInstanceMethodToMove();
        GodClass.someStaticMethodToMove();
    }
}

创建新类:

public class SingleResponsibilityClass {
}

静态方法可以SingleResponsibilityClass通过使用 Eclipse 的Refactor>Move...重构直接移动到 Prabhakaran 所描述的:

public class GodClass {
    public someInstanceMethodToMove() {
         // some code 1
    }

    public static void main(String[] args) {
        GodClass c = ...;
        c.someInstanceMethodToMove();
        SingleResponsibilityClass.someStaticMethodToMove();
    }
}

public class SingleResponsibilityClass {
    public static someStaticMethodToMove() {
         // some code 2
    }
}

对于实例方法,过程稍微复杂一些。参见下文。

从中提取一个方法someInstanceMethodToMove()并命名它someInstanceMethodToMove2()

public class GodClass {
    public someInstanceMethodToMove() {
        someInstanceMethodToMove2();
    }

    private someInstanceMethodToMove2() {
         // some code 1
    }

    // ...
}

SingleResponsibilityClass在原始方法中使用:

public class GodClass {
    public someInstanceMethodToMove() {
        someInstanceMethodToMove2(new SingleResponsibilityClass());
    }

    private someInstanceMethodToMove2(SingleResponsibilityClass obj) {
         // some code 1
    }

    // ...
}

注意:重要的SingleResponsibilityClass是要移动的实例方法的一个参数,否则Eclipse不会将它移动到这种类型。从那里,右键单击someInstanceMethodToMove2(),然后选择Refactor> Move...,在向导中选择 SingleResponsibilityClass 类型,然后应用:

public class GodClass {
    public someInstanceMethodToMove() {
        new SingleResponsibilityClass().someInstanceMethodToMove2();
    }

    // ...
}

public class SingleResponsibilityClass {
    private someInstanceMethodToMove2() {
         // some code 1
    }

    public static someStaticMethodToMove() {
         // some code 2
    }
}

然后右键单击SingleResponsibilityClass'someInstanceMethodToMove2()方法和Refactor>RenamesomeInstanceMethodToMove(): public class GodClass { public someInstanceMethodToMove() { new SingleResponsibilityClass().someInstanceMethodToMove(); }

    // ...
}

public class SingleResponsibilityClass {
    private someInstanceMethodToMove() {
         // some code 1
    }

    public static someStaticMethodToMove() {
         // some code 2
    }
}

然后右键单击GodClass'someInstanceMethodToMove()方法和Refactor> Inline

public class GodClass {
    public static void main(String[] args) {
        GodClass c = ...;
        new SingleResponsibilityClass().someInstanceMethodToMove();
        SingleResponsibilityClass.someStaticMethodToMove();
    }
}

public class SingleResponsibilityClass {
    private someInstanceMethodToMove() {
         // some code 1
    }

    public static someStaticMethodToMove() {
         // some code 2
    }
}
于 2015-04-01T23:00:37.243 回答
1
  1. 将该方法复制到新类中。
  2. 将旧类中的方法体替换为对新类的调用。
  3. 内联旧方法。

这就是你所需要的。它可能不是那么简单,因为在第 1 步和第 2 步中,您可能需要添加参数和/或将方法设为静态,但这是如何做到这一点的本质。

于 2013-11-15T14:48:24.133 回答
1

有没有让你满意的

package com.hussi.stackOverFlow;
class ClassOne {

    public void methodInClassOne(String stringParam)
    {
        ClassTwo classTwoObj = new ClassTwo();
        classTwoObj.methodInClassTwo(stringParam);
    }

}


class ClassTwo {

    public void methodInClassTwo(String stringParam)
    {
        System.out.println(stringParam);
    }

}


public class ClassThree {

    public static void main(String[] args) 
    {
        ClassOne objClassOne = new ClassOne();
        // calling method of class two in class one
        objClassOne.methodInClassOne("pass this String value");

    }

}
于 2013-11-15T06:55:04.710 回答
0

如果您使用任何标准 IDE(例如,EclipseIntelliJ IDEA),它们都有一个简单的菜单选项来执行此操作(取决于代码的组织方式)。

如果您转到每个方法并右键单击其名称,菜单有一个“重构”选项,它会导致一个“移动”选项。选择它并按照说明进行操作。

以上对于静态方法来说尤其容易。对于非静态的,您可能需要进行子类化,或将引用传递给适当的对象。即便如此,“重构 -> 移动”选项是一个好的开始。

于 2013-11-15T06:44:53.110 回答