In If else branches, what is the preferred approach? [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am writing a validation function, which checks a multitude of conditions and returns Success if none of the checks fail. I want to know, what would be the preferred way among two choices and why ?
private ResponseObj validationFunc1(ObjA objA, ObjB objB, ObjC objC){
ResponseObj responseObj = new ResponseObj();
if(condA){
responseObj.setStatus("FAILURE");
responseObj.setMessage("condA message");
return responseObj;
} else if(condB){
responseObj.setStatus("FAILURE");
responseObj.setMessage("condB message");
return responseObj;
} ....
...
}else if(condZ){
responseObj.setStatus("FAILURE");
responseObj.setMessage("condZ message");
return responseObj;
}
responseObj.setStatus("SUCCESS");
responseObj.setMessage("Valid");
return responseObj;
}
private ResponseObj validationFunc2(ObjA objA, ObjB objB, ObjC objC){
if(condA){
return new ResponseObj("FAILURE","condA message");
} else if(condB){
return new ResponseObj("FAILURE","condB message");
} ....
...
}else if(condZ){
return new ResponseObj("FAILURE","condZ message");
}
return new ResponseObj("SUCCESS","Valid");
}
Which of the above 2 functions would be preferred in production code ? If so, does one method has a performance gain over another ?
Or, Am I just mistaken and the compiled code for both the functions will be same ?
Thanks in advance for your answers. If I have asked the same question again, I am very sorry. I did try my best to search for this.

Which of the above 2 functions would be preferred in production code
Neither one.
Good code follows certain rules, especially for Java, nicely formulated in the "Clean Code" book by Robert Martin. Things that clean code strongly advocates against:
high number of parameters (and 2 is consider high already ;-)
doing multiple "things" within one method/class
So, at least for some people, (well written) production code would look much different.
What you could do for example: define an interface Validator, and then put each different validation into its own class implementing that interface. And then "multiple" checks turns into instantiating each of those classes, and putting the objects in some List<Validator> ... when you then iterate, and apply one after the other.
And note: performance doesn't matter here, too. The only thing that matters is how easy to read, understand, and maintain your code is. At least for me, the above ... isn't very good at that, for the reasons stated above.

Performance should be the same. You're making the same amount of comparisons and object creations in both cases.
Approach 1 is generally easier to trace later, especially in complicated functions. At the same time, something like
if (condition) {
// lots of code
// that scrolls and scrolls
// with its own fors and ifs and whiles
} else {
// by the time you're here, you've no idea what the corresponding if() was
}
can often be replaced with
if (!condition) {
return "error";
}
// lots and lots of code
and become more readable in the process. To summarize, there is not really a right answer, use your judgement and pick the variant you feel is easier to understand

The second example probably performs better because it has less method calls. However, it is so negligible that you really need to stop caring about it.
More importantly, the second example is more readable and less prone to bugs. For the first example, you have to worry about where responseObj came from and how corrupted its state may already be before you even get to it.

To review your sample.
Always prefer immutability, so your second approach would be
better.
Returning early the code easy to follow so you don't have to
scroll all the way down.
Returning a new
ResponseObj("SUCCESS","Valid") is not a good structure cause it
would open the gate to be (incorrectly) create a new
ResponseObj("SUCCESS","Failure"). I'd suggest replacing it by an
enum with both fields, which would also make the check for success
easier downstream.
Keep it easy with the args as already pointed out

2nd approach is better, because in 1st approach code is tightly coupled and have repeated lines.
1) For tightly coupled:
If the class provider ResponseObj is third person if they renamed the data members and their respective setters and getters then you also have to change where ever you have implemented.
2) Repeated lines of code:
responseObj.setStatus("FAILURE"); there are so much same lines of code which we can see in every condition, and we dont know how many goes with number of conditions.
Solution: I feel 2nd Apparoach is better, however every thread should create a new object and constructors can be create any numbers as per the required(Overloading) without impacting to existing implemented developers.

Related

Using optionals, is it possible to return early on "ifPresent" without adding a separate if-else statement?

public Void traverseQuickestRoute(){ // Void return-type from interface
findShortCutThroughWoods()
.map(WoodsShortCut::getTerrainDifficulty)
.ifPresent(this::walkThroughForestPath) // return in this case
if(isBikePresent()){
return cycleQuickestRoute()
}
....
}
Is there a way to exit the method at the ifPresent?
In case it is not possible, for other people with similar use-cases: I see two alternatives
Optional<MappedRoute> woodsShortCut = findShortCutThroughWoods();
if(woodsShortCut.isPresent()){
TerrainDifficulty terrainDifficulty = woodsShortCut.get().getTerrainDifficulty();
return walkThroughForrestPath(terrainDifficulty);
}
This feels more ugly than it needs to be and combines if/else with functional programming.
A chain of orElseGet(...) throughout the method does not look as nice, but is also a possibility.
return is a control statement. Neither lambdas (arrow notation), nor method refs (WoodsShortcut::getTerrainDifficulty) support the idea of control statements that move control to outside of themselves.
Thus, the answer is a rather trivial: Nope.
You have to think of the stream 'pipeline' as the thing you're working on. So, the question could be said differently: Can I instead change this code so that I can modify how this one pipeline operation works (everything starting at findShortCut() to the semicolon at the end of all the method invokes you do on the stream/optional), and then make this one pipeline operation the whole method.
Thus, the answer is: orElseGet is probably it.
Disappointing, perhaps. 'functional' does not strike me as the right answer here. The problem is, there are things for/if/while loops can do that 'functional' cannot do. So, if you are faced with a problem that is simpler to tackle using 'a thing that for/if/while is good at but functional is bad at', then it is probably a better plan to just use for/if/while then.
One of the core things lambdas can't do are about the transparencies. Lambdas are non-transparant in regards to these 3:
Checked exception throwing. try { list.forEach(x -> throw new IOException()); } catch (IOException e) {} isn't legal even though your human brain can trivially tell it should be fine.
(Mutable) local variables. int x = 5; list.forEach(y -> x += y); does not work. Often there are ways around this (list.mapToInt(Integer::intValue).sum() in this example), but not always.
Control flow. list.forEach(y -> {if (y < 0) return y;}); does not work.
So, keep in mind, you really have only 2 options:
Continually retrain yourself to not think in terms of such control flow. You find orElseGet 'not as nice'. I concur, but if you really want to blanket apply functional to as many places as you can possibly apply it, the whole notion of control flow out of a lambda needs not be your go-to plan, and you definitely can't keep thinking 'this code is not particularly nice because it would be simpler if I could control flow out', you're going to be depressed all day programming in this style. The day you never even think about it anymore is the day you have succeeded in retraining yourself to 'think more functional', so to speak.
Stop thinking that 'functional is always better'. Given that there are so many situations where their downsides are so significant, perhaps it is not a good idea to pre-suppose that the lambda/methodref based solution must somehow be superior. Apply what seems correct. That should often be "Actually just a plain old for loop is fine. Better than fine; it's the right, most elegant1 answer here".
[1] "This code is elegant" is, of course, a non-falsifiable statement. It's like saying "The Mona Lisa is a pretty painting". You can't make a logical argument to prove this and it is insanity to try. "This code is elegant" boils down to saying "I think it is prettier", it cannot boil down to an objective fact. That also means in team situations there's no point in debating such things. Either everybody gets to decide what 'elegant' is (hold a poll, maybe?), or you install a dictator that decrees what elegance is. If you want to fix that and have meaningful debate, the term 'elegant' needs to be defined in terms of objective, falsifiable statements. I would posit that things like:
in face of expectable future change requests, this style is easier to modify
A casual glance at code leaves a first impression. Whichever style has the property that this first impression is accurate - is better (in other words, code that confuses or misleads the casual glancer is bad). Said even more differently: Code that really needs comments to avoid confusion is worse than code that is self-evident.
this code looks familiar to a wide array of java programmers
this code consists of fewer AST nodes (the more accurate from of 'fewer lines = better')
this code has simpler semantic hierarchy (i.e. fewer indents)
Those are the kinds of things that should define 'elegance'. Under almost all of those definitions, 'an if statement' is as good or better in this specific case!
For example:
public Void traverseQuickestRoute() {
return findShortCutThroughWoods()
.map(WoodsShortCut::getTerrainDifficulty)
.map(this::walkThroughForestPath)
.orElseGet(() -> { if (isBikePresent()) { return cycleQuickestRoute(); } });
}
There is Optional#ifPresentOrElse with an extra Runnable for the else case. Since java 9.
public Void traverseQuickestRoute() { // Void return-type from interface
findShortCutThroughWoods()
.map(WoodsShortCut::getTerrainDifficulty)
.ifPresentOrElse(this::walkThroughForestPath,
this::alternative);
return null;
}
private void alternative() {
if (isBikePresent()) {
return cycleQuickestRoute()
}
...
}
I would split the method as above. Though for short code () -> { ... } might be readable.

Better to abstract out detail or use a setter? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
In terms of best practices, suppose I have this code:
public class ClassObject {
private int someNumber;
public void setSomeNumber(int x){
this.someNumber = x;
}
public int getSomeNumber(int x){
return this.someNumber;
}
//Should I even use this?
public void decreaseSomeNumber(){
--this.someNumber;
}
}
public void doSomeStuff(ClassObject instance){
// do some things
instance.decreaseSomeNumber(); //A
instance.setSomeNumber(instance.getSomeNumber() - 1); //B
}
I am wondering if either lines A or B are code smells. I think decreaseSomeNumber() is likely a redundant/useless function since I can just do instance.setSomeNumber(instance.getSomeNumber() - 1); everwhere.
On the other hand, it seems slightly more verbose doing instance.setSomeNumber(instance.getSomeNumber() - 1). What is the cleanest and good code design between A and B?
If you have a multithreaded environment, having (A) a decreaseSomeNumber method is worth it, however, you should make it threadsafe. Otherwise (B) two parallel threads might try to decrease the value at the same time, resulting in just a single decrease operation if they overlap.
That being said, it's typically hard work to really make code threadsafe, and in simple cases, occasional glitches might not matter. However, occasional is the keyword here: If you ever run into these, reproducing the problem will be horribly hard.
In terms of best practises you must avoid when is possible the form
public void decreaseSomeNumber(){
--this.someNumber;
}
and prefer the standard getters and setters.
But in some cases you need to decrease the value of a variable,
if this thing is occasional is good to use getters and setters
instance.setSomeNumber(instance.getSomeNumber() - 1);
instead in the case you need decreasing the a variable repeatedly (ex. A withdraw in a bank account) using only one method is not bad, but it must be defined like
public void decreaseSomeNumber(int many){
this.someNumber -= many;
}
in this way you are making a code more reusable, and this is good
P.S. the B way is more simple to syncronize in multi-threading enviroments
I would say it depends on more specific details, but I would be probably in favour of decreaseSomething.
With the getter and setter, you implicitly assume that:
The user of the API implements some (albeit trivial) computation.
The computation is performed at the time of the request.
The caller handles to concurrency-related issues on their own.
The (1) is rather a philosophical problem, although it might lead to errors caused by inadvertence, like calling get and set on two different objects.
The (2) can be a practical problem. Maybe you want to use the object from multiple threads. And maybe you don't need the number often, but you need to change it often. I believe that one could come up with some optimizations based on LongAdder or LongAccumulator or AtomicInt, which can optimize some highly concurrent places. With decreaseSomething, you can do it inside the class implementation. With getters and setters, you would need to somehow replace all occurences of x.setSomething(x.getSomething() + 1) by something else. That does not look like a proper encapsulation…
The (3) depends on your objective. Some people just make thread-unsafe code and claim it is programmer's responsibility to handle locks where needed, which can be OK. Sometimes, there might be a demand for thread-safe code. With getter and setter, you would need to use some locking scheme every time you access the data (which also makes (1) a less philosophical issue). Sometimes, it can be awful. Sometimes, it can be OK, because the caller wants to lock something more than just this one object.
As mentioned on the start of the post, I don't say I would prefer it every time. Maybe there are some cases when I would not go this way.
Edited
I would recommend changing this class as follows:
public class ClassObject {
private final int someNumber;
public ClassObject(int someNumber) {
this.someNumber = someNumber;
}
public int getSomeNumber() {
return someNumber;
}
public ClassObject decreaseSomeNumber() {
return new ClassObject(someNumber - 1);
}
public void doSomeStuff(ClassObject instance) {
//New ClassObject with new someNumber(instance's someNumber is decreased one unit)
ClassObject decreasedNumberClassObject = instance.decreaseSomeNumber();
}
}
I mean, if you wanna make a change in the Class properties(decrease, increase, multiply,...), it must return you, new Object(from the same Class), with the new property.
This code completely follows OOP paradigms. It is thread-safe, immutable and software(code) maintenance will be very high with the help of this approach.

Best practice or any performance implication for assignment vs multiple returns [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
During a code review, another dev and I had a small debate about the proper or correct way to handle multiple returns, and if assigning a pointer to null, and then setting it yields any difference compared to simply returning the value, an later returning null.
private ServiceParam getRequestServiceParam(SlingHttpServletRequest request) {
ServiceParam sp = null;
try {
sp = new ServiceParam(IOUtils.toString(request.getReader()));
} catch (IOException e) {
LOGGER.error("IOException", e);
}
return sp;
}
vs
private ServiceParam getRequestServiceParam(SlingHttpServletRequest request) {
try {
return new ServiceParam(IOUtils.toString(request.getReader()));
} catch (IOException e) {
LOGGER.error("IOException", e);
}
return null;
}
Functionally they seem identical, but we don't know if one my be more correct than the other. Though I fear that this may just be a tabs vs spaces argument.
Whether more than one return from a method is ok or not is a matter of opinion. But there are trade-offs here to talk about where some of the solutions are better than others. Sonarqube complaints are a good place to start, but there are larger issues.
Some people think it's bad to have more than one return and they want to follow the structured programming rules no matter what. Structured programming is better than using goto, and it does produce consistent-looking code.
Other people point out that enforcing one return makes control statement nesting deeper, resulting in code that is harder to read. In the case of the first example I find myself scanning up and down in the method looking for where the local variable gets a value assigned to it, and I think that's annoying.
(Sonarqube doesn't count cyclomatic complexity correctly when you have multiple returns, btw. So if it nags you to avoid that practice maybe there is an element of self-interest there; it's telling you, don't go writing code that we have trouble figuring out.)
Also there is no performance implication to any of this. It is just a matter of awkward coding and less-than-ideal exception-handling. When you return null you create an opportunity for the calling code to fail to check the reference for null, it would be better to let the exception get thrown.
I would not use Optional for this unless it looked like something I'd use in a monadic context where I'm chaining stuff together and using flatMap to handle the Optional empty cases for me. Otherwise it is annoying to have to wrap and unwrap this, it is a bit better than returning null, only because it forces the calling code to consider the empty case.
In this case the actual awkwardness is caused by reading from the httprequest, which is what throws the IOException. You could add throws IOException to the method and let the exception be thrown. But it would be better to move that code to whatever servlet or web controller is getting the httprequest, and have any IOException thrown by calling it get handled in the same way as whatever else the servlet or controller does gets handled.
Once you move that request-reading code there is no compelling reason for this method to exist at all. Deleting unnecessary code is a good thing.
I would follow #khelwood advice. Use Optional if you don't want to handle the raised exception outside of the function call as indicated by #ControlAltDel
private Optional<ServiceParam> getRequestServiceParam(SlingHttpServletRequest request) {
try {
return Optional.of(new ServiceParam(IOUtils.toString(request.getReader())));
} catch (IOException e) {
LOGGER.error("IOException", e);
return Optional.empty();
}
}
if you must use null I would prefer the second approach
private ServiceParam getRequestServiceParam(SlingHttpServletRequest request) {
try {
return new ServiceParam(IOUtils.toString(request.getReader()));
} catch (IOException e) {
LOGGER.error("IOException", e);
return null;
}
}
because I don't have to think twice everything is stated as is. So no unnecessary variable declaration, no need to remember what is in it. (This argument is also true for the Optional approach.)
Update 1: This is true for two, maybe three return statements in a single method, if there are several return statement other solutions must be considered.
Update 2: There is also a sonar rule squid:S1142
IMHO
Multiple returns are error-prone when it comes to code maintenance. Multiple returns are not the easiest to read.
When it comes to choices like this I always choose the code that is easier to read by someone who didn't write it.
When someone else reads it a year from now they might be in a hurry, working on some emergency, and they want code they can understand fully at a glance.
I strive to write code that is super easy to read, i.e., less risky for someone else to refactor.
It is always good to avoid local variables where ever you can, for better performance. If you are too much concerned about readability, then go with Option 1, else go with Option 2. Have a look at this answer for details about assigning the result to a local variable before returning.

Is defining variables for every condition is better then using getter and setters?

I have two codes can anyone tell me which approach is the better and why.
Approach 1 -
if (("Male").equalsIgnoreCase(input.getSex()) || ("Female").equalsIgnoreCase(input.getSex())) {
// do something
}else{
//do somethong
}
Approach 2 -
String tempSex = input.getSex()
if (("Male").equalsIgnoreCase(tempSex) || ("Female").equalsIgnoreCase(tempSex)) {
// do something
}else{
//do somethong
}
this is one condition, in my code, I have a lot of conditions similar to this one. In some condition, I have to compare with a lot more Strings.
Is this a good approach to define variables for every condition or I can use getter and setters?
These two approaches are essentially identical in terms of performance assuming the getSex function is a trivial getter (if getSex is complex or involves changing some other state in the class then these two bits of code are NOT equivalent).
I would prefer the first from a style point of view in that the extra local variable is slightly confusing to the flow of the code.
However if you main purpose is using code of this form is to validate legal input (as it appears from your example) I would try to create a method
boolean input.isSexValid() to encapsulate that functionality which would make the code less repetitive and more readable.
Strong argument that this is primarily opinion based, but:
I vote Approach 2.
What if the getter is slow (like it has to go to a DB)? You have a redundant round trip to the DB.

Java : How to improvise if else statements [duplicate]

This question already has answers here:
Long list of if statements in Java
(15 answers)
Closed 7 years ago.
During recent java interview question regarding if then else was asked and question was put up in the way that if you are given with 1000 if else conditions like
if(condition 1){
task 1
}else if (condition 2){
task 2
}else if (condition 3){
task 3
}
...
else if (condition 1000){
task 1000
}
i was asked to improvise the above code . I gave the answer that it could be improvised by using switch . But interviewer was not satisfied and asked for another approach. But i was unable to explain it. So i want to know if there is any better approach to do it.
Apologies for asking such a dumb question but i really want to know answer
Thinking from the interviewer's perspective, the purpose of the question is to get an answer which would be segue to next question.
The below is one way to improve using Collection. For java interview Generics, Autoboxing would be a good segue and the following answer includes exactly that. You can improve it in various ways but the following would be an answer.
List<Integer> myRnage = new ArrayList<Integer>(1000);
for(Integer theIndex : myRnage) {
//do the task for theIndex at this point.
}
Alternatively the same can be answered with code using Apache libraries to
demonstrate the use of Range utility. Here is the SO link for that and more.
If condition is numeric comparison, you can create (or receive) a list of methods, and the index of method to be executed.
That way, you eliminate all the if and elses and simply call
methods[somePosition].Invoke()
PS:The code above isn't java, it's just an example that can be applied in any language.
use a hash table method to key into your conditions instead of checking each condition. Hashing is order 1, so it is faster than checking all conditions via if statements.
The standard method to solve such problems is using a dictionary and the Command Pattern.
This however requires to you have a simple mapping condition x -> key x which may or may not be possible depending on the use case. You can still encapsulate the condition in a more extensible way:
interface ConditionalCommand
extends Runnable
{
boolean isApplicable(conditionParams...);
}
where isApplicable() tests if the pre-conditions for running the ConditionCommand are met.
List<ConditionalCommand> commands;
The multiple ifs can then be condensed to looping over the command list:
for (ConditionalCommand cmd: commands) {
if (cmd.isApplicable(params)) {
cmd.run();
break; // or not, which allows multiple commands to be run
}
}
How the command list is obtained and stored is up to you. Commands may even be pulled from a database or similar.
Multiple if statements can be improved by switch statements sometimes, switch statements can look a bit better.
However, such things are ultimately window dressing. A long list of conditionals in code often means that there has been a design flaw. The interviewer may have been looking for a appreciation of this.
You could have suggested that the conditionals could have been replaced with polymorphism.
Consider this:
// Bad implementation that replies on condtionals
public static void Print(string animal, string quote){
switch(animal){
case "Dog":
Console.WriteLine("the dog woofed " + quote);
return;
case "Cat":
Console.WriteLine("the cat meowed " + quote);
return;
}
}
// Better implementation that pushes the detail of how animals talk into an animal object
public static void BetterPrint(Animal animal, string quote){
Console.WriteLine(animal.Speak(quote));
}
public interface IAnimal{
string Speak(string quote);
}
Through better design, conditionals have vanished. In general, in OO programming you want behavior to emerge from object interaction rather than long methods filled with switches and ifs.
The best solution depends a bit on the format of the "condition", but if it just happens that, e.g. the conditions are the integers 1 to 1000 (or more generally form a dictionary of some time), then you can form a map, of e.g. Map. Then your code reduces to
if(map.contains(condition)){
map.get(condition).doTask()
} else {
throw new Exception("Condition has no associated task")
}
which is cleaner, and it makes it easier to change the conditions.
There are many ways to do it. We can actually make it a O(1) operation. How? Using array.
class Runner(){
public static void main(String[] args){
Task[] taskList = new Task[1000];
//init taskList and fill it with tasks first
Task taskToDo = taskList[condition];
taskToDo.execute();
}
}
class Task{
public void execute(){
//code for each task
}
}
There is also something known as Command Pattern which can solve this problem as well. But implementing it with array or list works nicely as well.

Categories