【问题标题】:How to move a method from a class to another class when two classes are not at all related当两个类完全不相关时如何将方法从一个类移动到另一个类
【发布时间】:2013-11-28 11:41:53
【问题描述】:

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

【问题讨论】:

  • 虽然不看代码很难说什么,但我认为继承应该解决你的目的
  • 但我不想继承。制作新课程后,我将删除旧课程。
  • 我会移动引用,然后浏览所有显示错误的文件,然后按 Ctrl+Shift+O 来自动组织导入。
  • 使用静态方法创建实用程序类。因此,您可以在应用程序中的任何位置引用它,而无需创建对象等等。
  • @Sandhu :这将导致代码中的添加。我只想对代码进行重构。将一个类分成 2-3 个类,因为类的长度约为 2000 行。 eclipse 中没有任何功能可以自动更新引用以及移动

标签: java eclipse refactoring automated-refactoring decomposition


【解决方案1】:

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

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

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

【讨论】:

  • 试过 "Refactor -> Move" ,但对我不起作用。它说不存在移动的目标。我认为黑白类需要一些关系
  • 目标类必须可以从要移动的方法中访问并符合许多其他规则(例如,不调用 super 关键字)。很难猜出你的代码是什么样子的。如果都在 1 个类中,则创建目标类,在原始类中从这些类中声明一些虚拟变量,然后再次尝试重构 -> 移动路径。
  • 我试过了..方法被移动了,但引用没有......例如...... Class1 有方法 abc() 被移动到 Class2。现在方法已移动,但使用此方法的 class3 仍将其用作 class1Obj.abc() 而不是 class2obj.abc()。
【解决方案2】:

如果您使用 Eclipse IDE,那么重构会为您提供帮助。

【讨论】:

    【解决方案3】:

    我会这样做:

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

    Working Effectively with Legacy Code也是一本学习如何应用重构模式的好书

    【讨论】:

      【解决方案4】:

      有没有让你满意的地方

      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");
      
          }
      
      }
      

      【讨论】:

        【解决方案5】:
        1. 将方法复制到新类中。
        2. 将旧类中的方法体替换为对新类的调用。
        3. 内联旧方法。

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

        【讨论】:

          【解决方案6】:

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

          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 {
          }
          

          通过使用 Eclipse 的 Refactor > Move... 重构,可以将静态方法直接移动到 SingleResponsibilityClass,如 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 > Rename它到someInstanceMethodToMove(): 公共类上帝类{ 公共 someInstanceMethodToMove() { 新 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
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-03-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-25
            • 1970-01-01
            相关资源
            最近更新 更多