Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java code reuse without inheritance

Tags:

java

I have 2 methods calling same method names:

public void doSomething1(Obj1 obj1) {
    obj1.do1();
    obj1.do2();
    obj1.do3();
}

public void doSomething2(Obj2 obj2) {
    obj2.do1();
    obj2.do2();
    obj2.do3();
}

I would like to extract to "common code" in a third method, this would be possible if I could create a super class of Obj1 and Obj2 but I can't. There is no way make these 2 objects inherit from a super class. So my question is, is there a way in Java to do this kind of extraction when there is no link between objects, something like:

public void doSomething1(Obj1 obj1) {
    refactor(obj1);
}

public void doSomething1(Obj2 obj2) {
    refactor(obj2);
}

private void refactor(NewObj newObj) {
    newObj.do1();
    newObj.do2();
    newObj.do3();
}
like image 382
Ferdossi Avatar asked Dec 22 '25 01:12

Ferdossi


1 Answers

Yes, but it's ugly: Reflection. But before we get to that, let me push back on something in the question:

Use an interface

...this would be possible if I could create a super class of Obj1 and Obj2 but I can't. There is no way make these 2 objects inherit from a super class.

They don't have to: They can just implement the same interface, without inheriting from the same superclass:

public interface TheCommonInterface {
    void do1();
    void do2();
    void do3();
}

public class Obj1 implements TheCommonInterface {
    // ...
}

public class Obj2 implements TheCommonInterface {
    // ...
}

Then

private void refactor(TheCommonInterface obj) {
    obj.do1();
    obj.do2();
    obj.do3();
}

Use a wrapper

If for some reason you can't even add an interface, use a wrapper class (an adapter class) that implements the interface.

Use reflection

In the worst case, you can use reflection: Use any of the several mechanisms on Class that let you find methods (such a getMethod), and then use Method#invoke on that method:

public void refactor(Object obj) {
    Class cls = obj.getClass();
    cls.getMethod("do1").invoke(obj);
    cls.getMethod("do2").invoke(obj);
    cls.getMethod("do3").invoke(obj);
}

That example is re-discovering the methods every time. If you ran into a performance problem doing that, you might look at caching them.

like image 156
T.J. Crowder Avatar answered Dec 23 '25 15:12

T.J. Crowder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!