How to move a method from a class to another class when two classes are not at all related

16,193

Solution 1

I would do it this way:

  1. Ensure that your tests work and the code to be re-factored is covered. If you don't have tests write tests. They are your safety rope.
  2. Use the re-factoring pattern extract superclass to create the new class that you want to move some methods to.
  3. Use the re-factoring pattern pull up methods to move the methods along with the variables that they need to the superclass. Now you will see if the methods you want to move and the instance variables have dependencies to the other methods that you don't want to move. If so you must first break this dependencies.
  4. Find all client code that should use the new extracted class instead of the "old" class and rewrite it to the new extracted class.
  5. Remove the "extends" relationship between the two classes. Now the client code should work or you missed something.

Also a good book for learning how to apply re-factoring patterns is Working Effectively with Legacy Code

Solution 2

if you using eclipse IDE then refactor will help you.

enter image description here

Solution 3

I will show you the process I follow. Consider such code:

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

Create the new class:

public class SingleResponsibilityClass {
}

The static method can be directly moved to the SingleResponsibilityClass by using Eclipse's Refactor > Move... refactoring as described by 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
    }
}

For the instance method, the process is a little more complex. Read below.

Extract a method out of someInstanceMethodToMove() and let's name it someInstanceMethodToMove2():

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

    private someInstanceMethodToMove2() {
         // some code 1
    }

    // ...
}

Use the SingleResponsibilityClass in the original method:

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

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

    // ...
}

Note: it is important that SingleResponsibilityClass is a parameter of the instance method to move, otherwise Eclipse will not move it to this type. From there, right click on someInstanceMethodToMove2(), and select Refactor > Move..., select SingleResponsibilityClass type in the wizard, then apply:

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

    // ...
}

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

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

Then right click on SingleResponsibilityClass' someInstanceMethodToMove2() method and Refactor > Rename it to someInstanceMethodToMove(): public class GodClass { public someInstanceMethodToMove() { new SingleResponsibilityClass().someInstanceMethodToMove(); }

    // ...
}

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

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

Then right click on GodClass' someInstanceMethodToMove() method and 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
    }
}

Solution 4

does it have any of your satisfaction

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

    }

}

Solution 5

  1. Copy the method into the new class.
  2. Replace the method body in the old class with a call into the new class.
  3. Inline the old method.

That's all you need. It may not be quite that simple, because in steps 1 and 2 you may need to add arguments and/or make the method static, but that is the essence of how to do it.

Share:
16,193
Shruti Rawat
Author by

Shruti Rawat

Updated on June 07, 2022

Comments

  • Shruti Rawat
    Shruti Rawat almost 2 years

    I am trying to re factor some code by breaking a class into several other classes. to do so i want to move some methods already existing in my old class to new class. But these methods are being referred in a lot of places and manually updating the references seems tiresome. So is there any way to move methods as well as update their references in eclipse?

  • Shruti Rawat
    Shruti Rawat over 10 years
    Tried "Refactor -> Move" , but not working for me. It says no target exists to move. I think some relation is required b/w classes
  • PNS
    PNS over 10 years
    The target class has to be reachable from within the method to be moved and conform to numerous other rules (e.g., not call the super keyword). It is difficult to guess what your code looks like. If it is all in 1 class, create the target classes, declare some dummy variables from these classes in the original class and try the Refactor -> Move path again.
  • Shruti Rawat
    Shruti Rawat over 10 years
    I tried.. method got moved but references didnt... For example.... Class1 has method abc() to be moved to Class2. Now method moved but class3 which was using this method is still using it as class1Obj.abc() and not class2obj.abc().