Som
Som

Reputation: 1610

Identify the caller inside a method in Java

I have a class A and class B as below :

class A {
    public String myMethod(){
        // do-something
        return send();
    }

    public String send(){
        // sending for A;
    }
}

class B {
    public String myMethod(){
        // do-something
        return send();
    }

    public String send(){
        // sending for B;
    }
}

Now the myMethod() is same in both the class but the implementation for send() method is different for class A and B. I am trying to implement the myMethod() inside a Utility class to avoid the duplication of method logic.

class Util {
    public String myMethod(){
        // do-something
        return send();
    }
}

But while calling the send(), how would I identify which object actually calls the method so that I can redirect to the appropriate send() method. Do I need the instanceOf in java or or what is a better approach for this problem.

Upvotes: 3

Views: 155

Answers (2)

Anthony Raymond
Anthony Raymond

Reputation: 7872

You should use inheritance to achieve this instead of extracting the generic method in a utility class that will need a parameter or reflection to identify the caller.

public interface MyInterface {
    default public String myMethod() {
        // do-something
        return send();
    }

    public String send();
}
public class A implements MyInterface {
    @Override
    public String send() {
        // send for A
    }
}
public class B implements MyInterface {
    @Override
    public String send() {
        // send for B
    }
}

Using inheritance you can put the myMethod code in the interface and implement the send differently in child classes.

Upvotes: 4

Oleg Cherednik
Oleg Cherednik

Reputation: 18255

This is an alternative solution to Anthony Raymond:

public interface Send {
    String send();
}

public class A implements Send {
    public String myMethod(){
        return Util.myMethod(this);
    }

    @Override
    public String send(){
        // sending for A;
    }
}

public class B implements Send {
    public String myMethod(){
        return Util.myMethod(this);
    }

    @Override
    public String send(){
        // sending for B;
    }
}

public final class Util {
    
    private Util() {}
    
    public static String myMethod(Send caller){
        // do-something
        return caller.send();
    }
}

Another solution is to use Decorator Pattern:

public interface Send {
    String send();
}

public class SendDecorator implements Send {
    private final Send delegate;
    
    public SendDecorator(Send delegate) {
        this.delegate = delegate;
    }
    
    @Override
    public String send(){
        // do-something
        return delegate.send();
    }
}

public class A implements Send {

    @Override
    public String send(){
        // sending for A;
    }
}

public class B implements Send {

    @Override
    public String send(){
        // sending for B;
    }
}

Send A = new SendDecorator(new A());
Send B = new SendDecorator(new B());

Upvotes: 2

Related Questions