Reputation: 129
I want to use switch instead of if-else as I've that it's better when there are many if-else. The problem is that I've multiple arguments, so I don't know how to handle that.
Here are my if-else's:
if(frame.height()/2 + margin < pt.y){
System.out.println("down");
drone.getCommandManager().down(20).doFor(100);
drone.getCommandManager().hover();
}
else if(frame.height()/2 - margin > pt.y){
System.out.println("up");
drone.getCommandManager().up(20).doFor(100);
drone.getCommandManager().hover();
}
else if(frame.width()/2+margin < pt.x){
drone.getCommandManager().spinRight(30).doFor(33);
drone.getCommandManager().hover();
System.out.println("RIGHT");
}
else if(frame.width()/2-margin > pt.x){
drone.getCommandManager().spinLeft(30).doFor(33);
drone.getCommandManager().hover();
System.out.println("LEFT");
}
else if(frame.width()/2+margin > pt.x && frame.width()/2-margin<pt.x){
System.out.println("GO");
drone.getCommandManager().forward(30).doFor(time+2000);
drone.getCommandManager().hover();
}
else{
drone.getCommandManager().hover();
}
Upvotes: 1
Views: 369
Reputation: 140427
You might step back for a second and read about the TDA principle.
What you are doing here in essence is: query the state of something, and then make decisions on how something else should be reacting to that. Thing is - that is really not object-oriented thinking.
You could instead go for:
interface CommandManagerUpdater {
void updateOnNewDirection(CommandManager);
}
enum Direction { UP, DOWN, ... };
class DirectionDetector {
Direction getNewDirection(Frame, x, yz, whatever you need)
class CommandManagerUpdaterFactory {
CommandManagerUpdater generateUpdaterFor(Direction newDirection) {
If you have the above means in place, you can write up the whole thing as:
Direction newDirection = someDetector.getNewDirection(...)
CommandManagerUpdater updater = theFactory.generateUpdaterFor(newDirection);
updater.updateOnNewDirection(commandManager);
Long story short: in OO programming, you should avoid this kind of if/else/switch statements. Instead: you create proper OO abstractions; and use factories and polymorphism. And let me be very clear about this: switch statements are not the answer to your problems. They are just a syntactically-marginally-improved version of if/else trees.
Of course, in the end, you need to a switch on "direction". But: you hide that switch inside the factory. There should be as few places as possible concerned about knowing all the potential directions.
Finally: keep an eye on code duplication. Check out how many times you have that "hoover()" call in your code - most them could go away! You know, when you go "hoover" all the time, for each of your direction; then you call write down that call once unconditionally, instead of repeating it n times in each of your branches!
Upvotes: 3
Reputation: 5578
I fully agree with what Jägermeister said. I think you should use proper OO principles to improve your code, but if you really wanted a switch...
You should convert the expressions you have into single values. You could use an enum like:
public enum Result {
A, B, C, D, E, F
}
Of course you should give it meaningful names!
Then you can have a method which converts the expression into result:
public Result calculateResult() {
if (frame.height() / 2 + margin < pt.y) {
return A;
} else if (frame.height() / 2 - margin > pt.y) {
return B;
} else if (frame.width() / 2 + margin < pt.x) {
return C;
} else if (frame.width() / 2 - margin > pt.x) {
return D;
} else if (frame.width() / 2 + margin > pt.x && frame.width() / 2 - margin < pt.x) {
return E;
} else {
return F;
}
}
Which in the end you can use in the switch:
switch (calculateResult()) {
case A:
System.out.println("down");
drone.getCommandManager().down(20).doFor(100);
drone.getCommandManager().hover();
break;
case B:
System.out.println("up");
drone.getCommandManager().up(20).doFor(100);
drone.getCommandManager().hover();
break;
case C:
drone.getCommandManager().spinRight(30).doFor(33);
drone.getCommandManager().hover();
System.out.println("RIGHT");
break;
case D:
drone.getCommandManager().spinLeft(30).doFor(33);
drone.getCommandManager().hover();
System.out.println("LEFT");
break;
case E:
System.out.println("GO");
drone.getCommandManager().forward(30).doFor(time + 2000);
drone.getCommandManager().hover();
break;
case F:
drone.getCommandManager().hover();
break;
}
Upvotes: 0
Reputation: 1342
You can't.
The labels in a switch
must be compile time evaluable constant expressions, and must compare exactly with the thing being switched on.
Upvotes: 3