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.
Related
When i see code from others, i mainly see two types of method-styling.
One looks like this, having many nested ifs:
void doSomething(Thing thing) {
if (thing.hasOwner()) {
Entity owner = thing.getOwner();
if (owner instanceof Human) {
Human humanOwner = (Human) owner;
if (humanOwner.getAge() > 20) {
//...
}
}
}
}
And the other style, looks like this:
void doSomething(Thing thing) {
if (!thing.hasOwner()) {
return;
}
Entity owner = thing.getOwner();
if (!(owner instanceof Human)) {
return;
}
Human humanOwner = (Human) owner;
if (humanOwner.getAge() <= 20) {
return;
}
//...
}
My question is, are there names for these two code styles? And if, what are they called.
The early-returns in the second example are known as guard clauses.
Prior to the actual thing the method is going to do, some preconditions are checked, and if they fail, the method immediately returns. It is a kind of fail-fast mechanism.
There's a lot of debate around those return statements. Some think that it's bad to have multiple return statements within a method. Others think that it avoids wrapping your code in a bunch of if statements, like in the first example.
My own humble option is in line with this post: minimize the number of returns, but use them if they enhance readability.
Related:
Should a function have only one return statement?
Better Java syntax: return early or late?
Guard clauses may be all you need
I don't know if there is a recognized name for the two styles, but in structured programming terms, they can be described as "single exit" versus "multiple exit" control structures. (This also includes continue and break statements in loop constructs.)
The classical structured programming paradigm advocated single exit over multiple exit, but most programmers these days are happy with either style, depending on the context. Even classically, relaxation of the "single exit" rule was acceptable when the resulting code was more readable.
(One needs to remember that structured programming was a viewed as the antidote to "spaghetti" programming, particularly in assembly language, where the sole control constructs were conditional and non-conditional branches.)
i would say it's about readability. The 2nd style which i prefer, gives you the opportunity to send for example messages to the user/program for any check that should stop the program.
One could call it "multiple returns" and "single return". But I wouldn't call it a style, you may want to use both approaches, depending on readability in any particular case.
Single return is considered a better practice in general, since it allows you to write more readable code with the least surprise for the reader. In a complex method, it may be quite complicated to understand at which point the program will exit for any particular arguments, and what side effects may occur.
But if in any particular case you feel multiple returns improve readability of your code, there's nothing wrong with using them.
I have to work out a result which depends on many models obtained from asynchronous calls. Those asynchronous calls performs network calls or UI interruptions (prompts for the user requiring him/her to choose something).
My first attempt has been just to invoke, recursively, to an ugly if/else nest, that looks like this:
public void getResult() {
if(mModelA == null) {
getModelA();
} else if(mModelB == null) {
getModelB(mModelA.someData);
} else if(mModelB.value == -1) {
askUserAboutValue();
} else if(mModelB.value == 5) {
getModelC();
} else if(mModelB.value == 3) {
getModelD();
} else if(...) {
....
}
}
The methods getModelX and askUserAboutValue perform asynchronous tasks and when they finish, they write some global variable and call getResult() in its callback.
I wonder if there is a pattern that could simplify this spaghetti code and what is more, to simplyfy its unit testing.
I think that isolating every check in simpler methods (like: checkModelA()) could help, but it might exist something better.
By the way, this is executed in the Activity of an Android application, so I'm constrained to have all this code in only one class.
Perhaps a switch would work better for this? Or just use a custom method that takes the Integer returned by mModelB.value? Notice the "Integer" not int to check for that null.
Another suggestion would be to use polymorphism, maybe create a method called "getModel(mModelB.value)".
Switch Case / If-Else problems are generally solution for bad design situation.
It looks like you should SubClass your ModelB so that Value of 5, -1 and 3 are different ChildClass which all relates to a Parent Class which would be a ModelB.
But from the function called in every If clause, it seems like -1 is not a SubClass but an error. It feels like in one single function you try to identify the right class that should be use and manage 1 case of error. Error case should be treated inside of the function called.
So in resume, this is a mess? I would gladly help you more but you will have to give me more info on what are those "value" and those "model" and how they interact with each other or their use so that I can try and come up with a better design. Your problem does not sit only on this If/Else function, it's bigger.
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.
I have written a constructor and passing one boolean flag to decide which value to set to class variable. Code is as follows
public PDFParagraph(PDFPhrase phrase,boolean isRtl) {
super(phrase);
if(isRtl)
this.setAlignment(Element.ALIGN_RIGHT);
else
this.setAlignment(Element.ALIGN_LEFT);
}
Now I am confused and not sure if I shall add if...else conditions in constructor. Is it good style to set the class varible value?
Thanks,
Hanumant.
Conditionals in constructors aren't problematic per se. However, in this instance, I'd be inclined to write your constructor like this:
public PDFParagraph(PDFPhrase phrase, boolean isRtl) {
super(phrase);
setAlignment(isRtl ? Element.ALIGN_RIGHT : Element.ALIGN_LEFT);
}
There is no style issue with using an if / else to do that. However:
You could write it more simply:
setAlignment(isRtl ? Element.ALIGN_RIGHT : Element.ALIGN_LEFT);
A lot of people (myself included) think that you should always put curly braces around the "then" and "else" statements.
On a related point: if you find yourself writing a constructor that looks like this:
public Thing(boolean cond, ...) {
super(...);
if (cond) {
// Lots of statements
} else {
// Lots of different statements
}
...
}
it is possibly an indication that you need to refactor your constructors. (Or possibly not ... it depends on the details.)
It might be more clear to users of your constructor if you just pass the initial alignment to set, especially if it's an Enum and those are the only possibilities. If however you're trying to restrict the initial alignment and it's something like a String, what you're doing seems fine. You still might want to consider an Enum for clarity though. It's easier to read than true or false being passed into a constructor.
Of course you can add if/else statements to the constructor.
It's usually best practice to keep methods as atomic (short and to-the-point) and clearly-defined as possible. This goes for the constructor also. You want the constructor to set up your object given the parameters you pass.
If you need an if/else, then you can put one in.
You can even go crazy and put a for loop in if you need to! ;)
I would recommend you use an enum and a switch statement instead of a boolean. What happens when you add another alignment?
Today I had a coworker suggest I refactor my code to use a label statement to control flow through 2 nested for loops I had created. I've never used them before because personally I think they decrease the readability of a program. I am willing to change my mind about using them if the argument is solid enough however. What are people's opinions on label statements?
Many algorithms are expressed more easily if you can jump across two loops (or a loop containing a switch statement). Don't feel bad about it. On the other hand, it may indicate an overly complex solution. So stand back and look at the problem.
Some people prefer a "single entry, single exit" approach to all loops. That is to say avoiding break (and continue) and early return for loops altogether. This may result in some duplicate code.
What I would strongly avoid doing is introducing auxilary variables. Hiding control-flow within state adds to confusion.
Splitting labeled loops into two methods may well be difficult. Exceptions are probably too heavyweight. Try a single entry, single exit approach.
Labels are like goto's: Use them sparingly, and only when they make your code faster and more importantly, more understandable,
e.g., If you are in big loops six levels deep and you encounter a condition that makes the rest of the loop pointless to complete, there's no sense in having 6 extra trap doors in your condition statements to exit out the loop early.
Labels (and goto's) aren't evil, it's just that sometimes people use them in bad ways. Most of the time we are actually trying to write our code so it is understandable for you and the next programmer who comes along. Making it uber-fast is a secondary concern (be wary of premature optimization).
When Labels (and goto's) are misused they make the code less readable, which causes grief for you and the next developer. The compiler doesn't care.
There are few occasions when you need labels and they can be confusing because they are rarely used. However if you need to use one then use one.
BTW: this compiles and runs.
class MyFirstJavaProg {
public static void main(String args[]) {
http://www.javacoffeebreak.com/java101/java101.html
System.out.println("Hello World!");
}
}
I'm curious to hear what your alternative to labels is. I think this is pretty much going to boil down to the argument of "return as early as possible" vs. "use a variable to hold the return value, and only return at the end."
Labels are pretty standard when you have nested loops. The only way they really decrease readability is when another developer has never seen them before and doesn't understand what they mean.
I have use a Java labeled loop for an implementation of a Sieve method to find prime numbers (done for one of the project Euler math problems) which made it 10x faster compared to nested loops. Eg if(certain condition) go back to outer loop.
private static void testByFactoring() {
primes: for (int ctr = 0; ctr < m_toFactor.length; ctr++) {
int toTest = m_toFactor[ctr];
for (int ctr2 = 0; ctr2 < m_divisors.length; ctr2++) {
// max (int) Math.sqrt(m_numberToTest) + 1 iterations
if (toTest != m_divisors[ctr2]
&& toTest % m_divisors[ctr2] == 0) {
continue primes;
}
} // end of the divisor loop
} // end of primes loop
} // method
I asked a C++ programmer how bad labeled loops are, he said he would use them sparingly, but they can occasionally come in handy. For example, if you have 3 nested loops and for certain conditions you want to go back to the outermost loop.
So they have their uses, it depends on the problem you were trying to solve.
I've never seen labels used "in the wild" in Java code. If you really want to break across nested loops, see if you can refactor your method so that an early return statement does what you want.
Technically, I guess there's not much difference between an early return and a label. Practically, though, almost every Java developer has seen an early return and knows what it does. I'd guess many developers would at least be surprised by a label, and probably be confused.
I was taught the single entry / single exit orthodoxy in school, but I've since come to appreciate early return statements and breaking out of loops as a way to simplify code and make it clearer.
I'd argue in favour of them in some locations, I found them particularly useful in this example:
nextItem: for(CartItem item : user.getCart()) {
nextCondition : for(PurchaseCondition cond : item.getConditions()) {
if(!cond.check())
continue nextItem;
else
continue nextCondition;
}
purchasedItems.add(item);
}
I think with the new for-each loop, the label can be really clear.
For example:
sentence: for(Sentence sentence: paragraph) {
for(String word: sentence) {
// do something
if(isDone()) {
continue sentence;
}
}
}
I think that looks really clear by having your label the same as your variable in the new for-each. In fact, maybe Java should be evil and add implicit labels for-each variables heh
I never use labels in my code. I prefer to create a guard and initialize it to null or other unusual value. This guard is often a result object. I haven't seen any of my coworkers using labels, nor found any in our repository. It really depends on your style of coding. In my opinion using labels would decrease the readability as it's not a common construct and usually it's not used in Java.
Yes, you should avoid using label unless there's a specific reason to use them (the example of it simplifying implementation of an algorithm is pertinent). In such a case I would advise adding sufficient comments or other documentation to explain the reasoning behind it so that someone doesn't come along later and mangle it out of some notion of "improving the code" or "getting rid of code smell" or some other potentially BS excuse.
I would equate this sort of question with deciding when one should or shouldn't use the ternary if. The chief rationale being that it can impede readability and unless the programmer is very careful to name things in a reasonable way then use of conventions such as labels might make things a lot worse. Suppose the example using 'nextCondition' and 'nextItem' had used 'loop1' and 'loop2' for his label names.
Personally labels are one of those features that don't make a lot of sense to me, outside of Assembly or BASIC and other similarly limited languages. Java has plenty of more conventional/regular loop and control constructs.
I found labels to be sometimes useful in tests, to separate the usual setup, excercise and verify phases and group related statements. For example, using the BDD terminology:
#Test
public void should_Clear_Cached_Element() throws Exception {
given: {
elementStream = defaultStream();
elementStream.readElement();
Assume.assumeNotNull(elementStream.lastRead());
}
when:
elementStream.clearLast();
then:
assertThat(elementStream.lastRead()).isEmpty();
}
Your formatting choices may vary but the core idea is that labels, in this case, provide a noticeable distinction between the logical sections comprising your test, better than comments can. I think the Spock library just builds on this very feature to declare its test phases.
Personally whenever I need to use nested loops with the innermost one having to break out of all the parent loops, I just write everything in a method with a return statement when my condition is met, it's far more readable and logical.
Example Using method:
private static boolean exists(int[][] array, int searchFor) {
for (int[] nums : array) {
for (int num : nums) {
if (num == searchFor) {
return true;
}
}
}
return false;
}
Example Using label (less readable imo):
boolean exists = false;
existenceLoop:
for (int[] nums : array) {
for (int num : nums) {
if (num == searchFor) {
exists = true;
break existenceLoop;
}
}
}
return exists;