Java style: Variable declaration in a switch - java

The following code does not compile because eater is defined twice:
switch (vegetable) {
case TOMATO:
Eater eater = new Eater(Tomato.class, many parameters);
eater.eat(more parameters);
return true;
case POTATO:
Eater eater = new Eater(Potato.class, many parameters);
eater.eat(more parameters);
return true;
case CARROT:
doSomethingElse();
return true;
}
Should I:
Use separate variables `tomatoEater` and `potatoEater`, making the code less maintainable?
Define `eater` before the `switch`, making it accessible to more than it should?
Define `eater` the first time only, leading to potential confusion?
Add braces, making the code more verbose?
Any better idea?

I would personally either use braces, or just abandon the local variable completely:
new Eater(Potato.class, many parameters)
.eat(more parameters);
The disadvantage of this is that it makes it a little harder to debug. Obviously this isn't your real code though... which makes it hard to say the right thing to do. It's quite possible that the right thing to do is actually to break out the bodies of the cases into separate methods.

Why not this:
switch (vegetable)
{
case TOMATO:
new Eater(Tomato.class, many parameters).eat(more parameters);
return true;
case POTATO:
new Eater(Potato.class, many parameters).eat(more parameters);
return true;
case CARROT:
doSomethingElse();
return true;
}
If you dont have any use of the Eater reference anywhere else later, I would do this.

Not quite the same logic as your method (carrot is treated as default) but shows an alternative approach (with some more behind the scenes wiring that I haven't worried about here):
Eater eater = vegetable.getEater(many parameters);
if (eater != null) eater.eat(more parameters);
else doSomethingElse();
return true;

How would using separate variables make the code less maintainable? (first bullet point). If anything I would say it would do the opposite as the variable name better explains what it is. I would go with that if keeping it in that scope is important to you.

Maybe using a switch isn't such a good idea at all.
In what better example can represent a switch statement in Java ?

Related

Design pattern for if-else with common logic within the conditionals

I have to implement a solution where the code behaves differently according to a different condition.
For example:
if(condition) {
//create one object
} else {
//create another object
}
oneCommonMethod();
if(condition) {
//do one thing
} else {
//do another thing
}
anotherCommonMethod();
Even the code inside the conditions is shared sometimes, it's just slightly variations of it. What would be the best approach here? What would be the best Design Pattern?
You might be looking for the Strategy Pattern for the do something aspect. For the create an object aspect you could see if any of the creational patterns such factory or factoryMethod suits your usecase.
Different strategies can call into shared methods when required
It is more efficient to have one "if-else" statement – whenever you can achieve the same goal with just one, there's no need to do an extra one and negatively affect performance.
In your code, given that the 'condition' is shared amongst both "if" statements (1), and given that the two "if" statements are at the same place in the program (2), it is better to merge the two "if" statments like this:
if(condition) {
//create one object
oneCommonMethod();
//do one thing
anotherCommonMethod();
} else {
//create another object
oneCommonMethod();
//do another thing
anotherCommonMethod();
}
This code achieves exactly the same goal as yours, except it's more effecient with just one "if" statement.

How to achieve a switch case block which is scalable?

While starting to build an application, I stared using a switch case block with only five cases to be considered. Later when the build progressed, more cases came into picture and that started creating problems. I know I might have designed it wrongly at the first place, but if such things come as a change how do I effectively approach this? An example is given below
Starting with this
switch case 1: /*do function1()*/ break;
case 2: /*do function2()*/ break;
Later, a 100 cases come in
switch case 1: /*do function1()*/ break;
case 2: /*do function2()*/ break;
....
case 100: /*do function100()*/ break;
I am sure that converting these cases into 100 if conditions is not going to be a very good approach, so is there a way this can be done?
Please consider that the functions given in the code above are simple mathematical functions for now.
Consider an interface like this:
public interface MyFunction {
public void compute();
}
and a Map with the previous interface as values:
Map<Integer,MyFunction> myFunctionsMap = new HashMap<>();
You need to initialize the map with all of you functions:
myFunctionsMap.put(1,new MyFuntion() {
#Override
public void compute() {
/*do function1()*/
}
});
for each of your functions, the syntax might be a bit heavy with anonymous classes, you can implement you functions in separate classes and use them as well.
Now instead of the switch, you simply use the map:
myFunctionsMap.get(theValueSwitched).execute();
Depending of how you initialize the map, the values of the keys and how you use it, you might want to check myFunctionsMap.contains(theValueSwitched) (this would be your default case if you have one).
Edit: Java 8 shorter syntax would be myFunctionsMap.put(1,() -> {/*do function1()*/});
You could name your methods something like method1, method2, method3 , etc .. and use reflexion to call them, using you variable. You wouldn't have a lengthy switch, that way.
I have no ideas if that is efficient or not, though.
Here's a neat exemple, from wikipedia's reflection page.
Object foo = Class.forName("complete.classpath.and.Foo").newInstance();
// Alternatively: Object foo = Foo.class.newInstance();
Method m = foo.getClass().getDeclaredMethod("hello", new Class<?>[0]);
m.invoke(foo);
hope that helps

Is it possible to use an Integer to call methods and arrays dynamically?

For example:
3 methods exist
"map1method,
map2method,
map3mehtod"
and I want to call the right one depending on what the integer 'activemap' has currently stored in it.
I could do an If statement
"If (activemap == 1)
map1method;
elseif (activemap ==2)
..."
But is there a possible way of using the integer more efficiently?
Like a "map(activemap)method"
Also could I also call a specific array in a batch of them in the same fashion.
This is all in java by the way.
It is possible via reflection but I would urge you to stay away from that approach. Why not have all three methods built into one? One option would be to use a switch statement to handle the various cases:
void mapMethod(int activemap) {
switch (activemap) {
case 1:
// map1method
break;
case 2:
// map2method
break;
case 3:
// map3method
break;
default:
break;
}
}
Now, you can call
mapMethod(activemap)
If you want to take the reflection approach instead (which as I said I don't think you should), you can do something along the lines of
String methodName = "map" + activemap + "method";
MyClass.class.getDeclaredMethod(methodName).invoke(null);
A switch statement would be slightly easier to read:
switch(activemap) {
case 1: map1method(); break;
case 2: map2method(); break;
}
You could use reflection to build the method name up at runtime, but that wouldn't be simpler. Reflection is a lot of code.
The most effective way to do this is to either create an enum to represent the different calls and use the int as a lookup for the enum value, or if that's not possible, to use a switch statement. You can use reflection to accomplish what you're talking about (look up a method at runtime based on its name), but it's less efficient and more cumbersome than either of those options.
You can do it using Reflection, It will be something like this:
java.lang.reflect.Method method;
method = myObject.getClass().getMethod("map+"activemap"+method", param1.class, param2.class, ..);
method.invoke(object, arg1, arg2,...);

Java - return or if-else [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Should a function have only one return statement?
This is what I am talking about.
if (condition) {
aVariable = 1;
return;
}
doSomething();
if (condition) {
aVariable = 1;
} else {
doSomething();
}
Is one of these preferred over the other (conventions, etc)?
Returning early can improve readability by reducing nesting in your code.
In some languages it is best practice to have a single return statement, for example in C++ you should allocate at the top and de-allocate at the bottom of your method, but Java is not such a language so prefer readability over a single return statement.
Many people use the single return rule because they don't understand why it exists or because they have a background in managed languages.
Please Note
Before you comment about the "one true way" of writing code, please pause for a moment and consider the following.
Why must there be only a single return statement?
If you can't think of a good reason, stop arguing that it should be the case.
Readability is most important.
So early returns on begining of functions are ok, but once method starts doing something more complicated than checking its imputs/state of object, it should have only one return .
And if it is too complicated, it should be refactored to multiple functions.
The second is preferred since methods should have only one return statement and it must be at the end of the method itself.
If you want to go deeper on that topic, there are many programs that do validations over your code. One of these is PMD. There is also a useful eclipse plugin to validate your code against the conventions you are looking for.
Once you hit the return the method ends and returns to the calling method in the stack.
public void myMethod(){
if (condition) {
aVariable = 1;
return;
}
doSomething();
}
and
public void myMethod(){
if (condition) {
aVariable = 1;
} else {
doSomething();
}
}
will do the same, but AFAIK it's preferred for any method to have only one exit point (at least it's what Edsger Dijkstra says)
For the best practice the return statement should be the last line
of function
Using else block is good method because if you want to add some other code in future the first block of code may need editing
note: All methods have it's on merits and cons. Their is no Silver bullet solution.
No, you can use both ways.
First way is also used when you have many other conditions, and return will move you out from method. In this way you have no nested conditions.
Either code snippet will work. It will depend on the context in which the code is being used.

Boolean checking in the 'if' condition

Which one is better Java coding style?
boolean status = true;
if (!status) {
//do sth
} else {
//do sth
}
or:
if (status == false) {
//do sth
} else {
//do sth
}
I would suggest that you do:
if (status) {
//positive work
} else {
// negative work
}
The == tests, while obviously redundant, also run the risk of a single = typo which would result in an assignment.
Former, of course. Latter is redundant, and only goes to show that you haven't understood the concept of booleans very well.
One more suggestion: Choose a different name for your boolean variable. As per this Java style guide:
is prefix should be used for boolean variables and methods.
isSet, isVisible, isFinished,
isFound, isOpen
This is the naming convention for
boolean methods and variables used
by Sun for the Java core packages.
Using the is prefix solves a common
problem of choosing bad boolean names
like status or flag. isStatus or
isFlag simply doesn't fit, and the
programmer is forced to chose more
meaningful names.
Setter methods for boolean variables
must have set prefix as in:
void setFound(boolean isFound);
There are a few alternatives to the
is prefix that fits better in some
situations. These are has, can and
should prefixes:
boolean hasLicense();
boolean canEvaluate();
boolean shouldAbort = false;
If you look at the alternatives on this page, of course the first option looks better and the second one is just more verbose. But if you are looking through a large class that someone else wrote, that verbosity can make the difference between realizing right away what the conditional is testing or not.
One of the reasons I moved away from Perl is because it relies so heavily on punctuation, which is much slower to interpret while reading.
I know I'm outvoted here, but I will almost always side with more explicit code so others can read it more accurately. Then again, I would never use a boolean variable called "status" either. Maybe isSuccess or just success, but "status" being true or false does not mean anything to the casual reader intuitively. As you can tell, I'm very into code readability because I read so much code others have written.
The first one, or if (status) { /*second clause*/ } else { /* first clause */ }
EDIT
If the second form is really desired, then if (false == status) <etc>, while uglier, is probably safer (wrt typos).
It really also depends on how you name your variable.
When people are asking "which is better practice" - this implicitly implies that both are correct, so it's just a matter of which is easier to read and maintain.
If you name your variable "status" (which is the case in your example code), I would much prefer to see
if(status == false) // if status is false
On the other hand, if you had named your variable isXXX (e.g. isReadableCode), then the former is more readable. consider:
if(!isReadable) { // if not readable
System.out.println("I'm having a headache reading your code");
}
The former. The latter merely adds verbosity.
The first one. But just another point, the following would also make your code more readable:
if (!status) {
// do false logic
} else {
// do true logic
}
Note that there are extra spaces between if and the (, and also before the else statement.
EDIT
As noted by #Mudassir, if there is NO other shared code in the method using the logic, then the better style would be:
if (!status) {
// do false logic
}
// do true logic
My personal feeling when it comes to reading
if(!status) : if not status
if(status == false) : if status is false
if you are not used to !status reading. I see no harm doing as the second way.
if you use "active" instead of status I thing if(!active) is more readable
First style is better. Though you should use better variable name
This is more readable and good practice too.
if(!status){
//do sth
}else{
//do sth
}

Categories

Resources