Reputation:
I've been wondering if there is a way for me to replace the current switch statement I have. Below is an example of the code I have, although the statement I have is a lot longer and will only get larger. The switch method gets called through a file reader so it reads a line then calls this function with values assigned.
public static void example(String action, String from, String to){
switch (action) {
case ("run"):
runTo(from,to);
break;
case ("walk"):
walkTo(from,to);
break;
case ("hide"):
hideAt(to);
break;
}
}
edit: I was curious if there is a better way instead of using a switch statement like the above scenario.
I've updated the example a bit to make a little more sense. Some of the method calls dont need to use all of the parameters.
Upvotes: 1
Views: 8261
Reputation: 150
Replacing a switch with method calls is definitely not utter nonesense @Stultuske. Usually you use method inheritance, so different child classes with the same parent class override a general method and you don't have to check for the subclass's type.
Your case on the other hand looks like a factory method, but parameters are a bit wildly mixed. I would suggest a Map
with String
to a wrapper constructor function. For the "ccc" case you have to think about something else (e. g. default arguments) or you always have the unused parameter i
.
Upvotes: -1
Reputation: 1218
For Java 7 and below we can declare an interface for function implementation.
for Java 8+ we can use Function interface.
Interface:
public interface FunctionExecutor {
public Object execute(String from,String to);
}
Function Context:
public class FunctionContect {
HashMap<String, FunctionExecutor> context=new HashMap<String, FunctionExecutor>();
public void register(String name,FunctionExecutor function){
context.put(name, function);
}
public Object call(String name,String from,String to){
return context.get(name).execute(from, to);
}
public FunctionExecutor get(String name){
return context.get(name);
}
}
Function Implementations:
public class RunFunctionImpl implements FunctionExecutor{
@Override
public Object execute(String from, String to) {
System.out.println("function run");
return null;
}
}
// OTHER FUCNTIONS
Register Function:
FunctionContect contex = new FunctionContect();
contex.register("run", new RunFunctionImpl());
contex.register("walk", new WalkFunctionImpl());
contex.register("hide", new HideFunctionImpl());
Call Function
context.call(action, from, to);
or
context.get(action).execute(from,to);
Upvotes: 6
Reputation: 691
One possible option to get rid of switch is to use hashmap of functions:
private String stringMethod(final String action, final String source) {
final Function<String, String> toLowerFunction = String::toLowerCase;
final Function<String, String> toUpperFunction = String::toUpperCase;
final HashMap<String, Function<String, String>> stringFunctions = new HashMap<>();
stringFunctions.put("toLower", toLowerFunction);
stringFunctions.put("toUpper", toUpperFunction);
return stringFunctions.get(action).apply(source);
}
Upvotes: 0
Reputation: 109613
If you have a repetion of switch cases on the same variable, say in method f
, g
and h
. Then you can turn things inside out:
void f(String a) {
switch (a) {
case "aaa": ... ; break;
...
}
}
void g(String a) {
switch (a) {
case "aaa": ... ; break;
case "bbb": ... ; break;
case "ccc": ... ; break;
...
}
}
void h(String a) {
switch (a) {
case "aaa": ... ; break;
...
}
}
Can be handled object orientedly as:
class C {
public f() { }
public g() { }
public h() { }
}
class Aaa extends C {
@Override
public f() { test3(b,c); } // Or even just the body of test3
@Override
public g() { }
@Override
public h() { }
}
class Bbb extends C {}
class Ccc extends C {}
Then once one has to provide a specific C:
C c;
switch (a) {
case "aaa": c = new Aaa(); break;
case "bbb": c = new Bbb(); break;
case "ccc": c = new Ccc(); break;
...
}
c.f(...);
c.g(...);
c.h(...);
This looks circumstantial, but in effect delivers an improvement on development quality. Adding a new case does not mean searching all switch cases.
The code of one case ("aaa") is all in one class, with its own dedicated fields. That can simplify things and deliver a better overview.
Upvotes: 0
Reputation: 298
I am not completely sure what you want to achieve. If you don't want to keep adding new
case ("ccc"):
Lmn(b,c,i);
break;
blocks.
You can hash the methods in a HashMap<string, method>
and get the method from the map using the key and execute it.
Upvotes: 0