Reputation: 31
Below I am trying to explain the problem with an example.
We have a Caller.java
Caller.java : which calls the series of Actors to perform certain steps in sequence.
Actor.java : Abstract class containing action() method
ActorOne.java : Implements the action() method
ActorTwo.java : Implements the action() method
ActorThree.java : Implements the action() method
At runtime, based on a task to accomplish, a collection of classes is prepared inside Caller.java and instantiated using the Reflection.
Actor.java: callActions(){
Class[] classes = [ActorOne.class, ActorTwo.class]
for(Class clazz : classes){
Actor actor = (Actor) clazz.newInstance();
actor.action();
}
}
In certain situation, which I know runtime inside the callActions.java, I need to inform the ActorTwo to peform the action method differently.
My solution is to pass that flag to the ActorTwo object using Reflection API and inside the action() method put if/else to perform the flag specific action.
Is there a better way to design the solution, so that I can avoid the if/else within the ActorTwo.action() method?
Best Regards
Upvotes: 0
Views: 63
Reputation: 7042
Another option is to make the action()
method take an array of arguments (like main(...)
does). That way ActorTwo could check the arguments to see if its in the special case, whereas the other Actors could just ignore the input.
public abstract class Actor{
public abstract void action(String[] args);
}
public class Actor2 extends Actor{
public void action(String[] args){
if(args != null && args.length > 0 && args[0].equals("SPECIAL_CASE"){
//Do special case things
} else {
//Do regular case things
}
}
}
This formation gives you the most flexibility going forward with adding extra cases to any actors.
Upvotes: 1
Reputation: 945
Use polymorphism. Define one more method in your ActorTwo.java called action(flag), and then implement the new behavior in this method. When you do not want to pass flag, normal action() should be called. When you want to pass flag, on runtime, you should call action(flag).
A word of advise, try to avoid reflection if possible. It slows down the execution. If it is not possible for your code to avoid reflection, that is fine.
Upvotes: 1
Reputation: 7403
You could have two methods on your interface. ActorOne and ActorThree would delegate the implementation of one method to the other (maybe an abstract super class would do that). ActorTwo would do something different.
You could have another interface with the different method, and have ActorTwo implement it, and at runtime check if your object supports it
if(inSpecialCase && actor instanceof Actor2) {
((Actor2)actor).specialMethod()
Eclipse works like the second suggestion a lot, to preserve extensibility and compatibility (new interfaces are created over time and the behavior adapts depending on what level the code supports).
Upvotes: 1