Is it a good idea to introduce variables only for the sake of readability?
Example 1:
while(nameNode1.charAt(0) == nameNode2.charAt(0) && nameNode1.length() > 1 && nameNode2.length() > 1)
{
nameNode1 = nameNode1.substring(1, nameNode1.length());
nameNode2 = nameNode2.substring(1, nameNode2.length());
}
Example 2:
boolean letterFromBothNodesAreEqual_andNameHasMoreThanOneLetter = nameNode1.charAt(0) == nameNode2.charAt(0) && nameNode1.length() > 1 && nameNode2.length() > 1;
while(letterFromBothNodesAreEqual_andNameHasMoreThanOneLetter)
{
nameNode1 = nameNode1.substring(1, nameNode1.length());
nameNode2 = nameNode2.substring(1, nameNode2.length());
}
It might be an extreme example, but i think you get the idea.
I haven't seen this in code and i was wondering if this is a useful approach?
Thank You
Context: I'm trying to make the transition from college to Entry-Level-Developer and currently I'm focusing on clean-coding.
It's always better to make code readable, just don't over do it too much where it's a maintenance nightmare, although most clean code is easier to maintain.
I would introduce two new methods here instead of variables, where your code example would be:
while(letterFromBothNodesAreEqual() && nameHasMoreThanOneLetter())
{
nameNode1 = nameNode1.substring(1, nameNode1.length());
nameNode2 = nameNode2.substring(1, nameNode2.length());
}
It's a common readability refactor to extract boolean conditions into their own function with a name. If a person is reading your code and comes across some if with a bunch of conditions, they will wonder what the significance of it is, why is the branch needed or what it represents. The fields alone might not tell them the answer, but they might know what it represents if the condition had a name (the name of the function).
Apart from the fact that the variable name in your example is a bit too verbose, yes.
One thing that is important though is to remember to keep the scope of local variables as small as possible. So don't declare local variables at the start of the method if they're only going to be used in an if block further down.
Edit: And one more thing I've just noticed: your two examples are NOT equivalent. In the first scenario the expression is recalculated on every iteration, in the second one it isn't. In cases like this you need a helper method as explained by #NESPowerGlove instead of a variable.
This question is quite subjective but the following holds true for all subjects. (I wanted to have a little fun with this answer)
private boolean isMoreReadable = true;
private boolean isEasyToMaintain = true;
private boolean isProperlyCommented = true;
private boolean isBugFree = true;
// This method checks if my co-workers are happy with my code
private boolean myCoWorkersHappyWithMyCode() {
return isMoreReadable && isEasyToMaintain && isProperlyCommented && isBugFree;
}
if (myCoWorkersHappyWithMyCode()) {
System.out.println("YES, you wrote good code so I don't see why not");
} else {
System.out.println("NO, keep learning to better yourself");
}
Yes offcourse its a good practice to name variables according to there work or functionality in the program.Because in case in the future if someone else works on your code then it will be easier for him to understand otherwise it will give him a headache same happens while working on distributed program your co-workers must understand variables work by there name.
Related
Can anyone assist me with an alternative to if then else statements for control flow? Or advise on a good article?
From what I've seen, some use mapping or enums. Trouble I'm having is that I have multiple conditions i.e. if (condition1 && condition2 && condition3)... and I need to do this for several permutations and all 3 variables need to be validated.
Please can someone point me in the right direction?
else if (String.Utils.isNotEmpty(payload.getKeyChange2TokenNumber()) && String.Utils.isEmpty(payload.getKeyChange1TokenNumber()) && String.Utils.isEmpty(payload.getKeyChange3TokenNumber()){
String.format(return value dependant on outcome of validation)
}
So no if then else statements, how can I implement a hashmap to determine what to return in place of the if then else statements return
Thank you.
So, a lot of people end up trying to avoid using if statements because they feel "there must be an easier and more cleaner way of doing this". However think fundamentally, code is just a bunch of if statements at the basic level.
So I wouldn't be too worried about using them, because by trying to use HashMaps or whatever, then you may be just using a nuclear bomb to kill a mosquito.
One thing to keep in mind is that you don't want nested if/else statements, it does become hard to check.
For your example, you mention that you have to do this check on the variables multiple times. So what's wrong with checking that they aren't empty at the start of the flow. If they are then exit or return with the corresponding result. You then don't need to do the checks again.
Additionally, it is useful to use short functions that describe what you're trying to do.
Instead of:
else if (String.Utils.isNotEmpty(payload.getKeyChange2TokenNumber())
&& String.Utils.isEmpty(payload.getKeyChange1TokenNumber())
&& String.Utils.isEmpty(payload.getKeyChange3TokenNumber()) {
String.format(return value dependant on outcome of validation)
}
Try:
if (notEmpty(payload.getKeyChange2TokenNumber())
&& notEmpty(payload.getKeyChange1TokenNumber())
&& notEmpty(payload.getKeyChange3TokenNumber())) {
String.format(return value dependant on outcome of validation)
}
private boolean notEmpty(String string) {
return StringUtils.isNotEmpty(string);
}
Additionally, if the above check is actually related to a domain related response then use that instead. For example, let's say getKeyChange1TokenNumber, getKeyChange2TokenNumber, getKeyChange3TokenNumber are all checked to determine whether the mandatory key change token numbers are provided and you cannot proceed if it isn't true. You're code would look like this:
public void main() {
if (mandatoryKeyChangeTokensNotProvided(payload)) {
return "Mandatory Key Change Tokens not provided";
}
...
}
private boolean mandatoryKeyChangeTokensNotProvided(Payload payload) {
return isEmpty(payload.getKeyChange2TokenNumber())
&& isEmpty(payload.getKeyChange1TokenNumber())
&& isEmpty(payload.getKeyChange3TokenNumber());
}
private boolean isEmpty(String string) {
return StringUtils.isEmpty(string);
}
Try to use the domain language in your code so it makes more sense to the dev. So a dev reading this would read the mandatoryKeyChangeTokensProvided method and know what it does. If they want to know how it does it, then just go into the method and see that its doing string empty checks against it. Hopefully this clears things up for you.
There are multiple ways you can do this, but it all depends on your domain. For example, you say this is validation? Whats wrong with having a Validator Class that does all these checks for you? But remember the KISS principle. Try not to overcomplicate things.
I have found myself using the following practice, but something inside me kind of cringes every time i use it. Basically, it's a precondition test on the parameters to determine if the actual work should be done.
public static void doSomething(List<String> things)
{
if(things == null || things.size() <= 0)
return;
//...snip... do actual work
}
It is good practice to return at the earliest opportunity.
That way the least amount of code gets executed and evaluated.
Code that does not run cannot be in error.
Furthermore it makes the function easier to read, because you do not have to deal with all the cases that do not apply anymore.
Compare the following code
private Date someMethod(Boolean test) {
Date result;
if (null == test) {
result = null
} else {
result = test ? something : other;
}
return result;
}
vs
private Date someMethod(Boolean test) {
if (null == test) {
return null
}
return test ? something : other;
}
The second one is shorter, does not need an else and does not need the temp variable.
Note that in Java the return statement exits the function right away; in other languages (e.g. Pascal) the almost equivalent code result:= something; does not return.
Because of this fact it is customary to return at many points in Java methods.
Calling this bad practice is ignoring the fact that that particular train has long since left the station in Java.
If you are going to exit a function at many points in a function anyway, it's best to exit at the earliest opportunity
It's a matter of style and personal preference. There's nothing wrong with it.
To the best of my understanding - no.
For the sake of easier debugging there should be only one return/exit point in a subroutine, method or function.
With such approach your program may become longer and less readable, but while debugging you can put a break point at the exit and always see the state of what you return. For example you can log the state of all local variables - it may be really helpful for troubleshooting.
It looks like there a two "schools" - one says "return as early as possible", whereas another one says "there should be only one return/exit point in a program".
I am a proponent of the first one, though in practice sometimes follow the second one, just to save time.
Also, do not forget about exceptions. Very often the fact that you have to return from a method early means that you are in an exceptional situation. In your example I think throwing an exception is more appropriate.
PMD seems to think so, and that you should always let your methods run to the end, however, for certain quick sanity checks, I still use premature return statements.
It does impair the readability of the method a little, but in some cases that can be better than adding yet another if statement or other means by which to run the method to the end for all cases.
There's nothing inherently wrong with it, but if it makes you cringe, you could throw an IllegalArgumentException instead. In some cases, that's more accurate. It could, however, result in a bunch of code that look this whenever you call doSomething:
try {
doSomething(myList);
} catch (IllegalArgumentException e) {}
There is no correct answer to this question, it is a matter of taste.
In the specific example above there may be better ways of enforcing a pre-condition, but I view the general pattern of multiple early returns as akin to guards in functional programming.
I personally have no issue with this style - I think it can result in cleaner code. Trying contort everything to have a single exit point can increase verbosity and reduce readability.
It's good practice. So continue with your good work.
There is nothing wrong with it. Personally, I would use else statement to execute the rest of the function, and let it return naturally.
If you want to avoid the "return" in your method : maybe you could use a subClass of Exception of your own and handle it in your method's call ?
For example :
public static void doSomething(List<String> things) throws MyExceptionIfThingsIsEmpty {
if(things == null || things.size() <= 0)
throw new MyExceptionIfThingsIsEmpty(1, "Error, the list is empty !");
//...snip... do actual work
}
Edit :
If you don't want to use the "return" statement, you could do the opposite in the if() :
if(things != null && things.size() > 0)
// do your things
If function is long (say, 20 lines or more), then, it is good to return for few error conditions in the beginning so that reader of code can focus on logic when reading rest of the function. If function is small (say 5 lines or less), then return statements in the beginning can be distracting for reader.
So, decision should be based on primarily on whether the function becomes more readable or less readable.
Java good practices say that, as often as possible, return statements should be unique and written at the end of the method. To control what you return, use a variable. However, for returning from a void method, like the example you use, what I'd do would be perform the check in a middle method used only for such purpose. Anyway, don't take this too serious - keywords like continue should never be used according to Java good practices, but they're there, inside your scope.
Is it really a good practice to avoid using NOT operator in IF conditions in order to make your code better readable? I heard the if (doSomething()) is better then if (!doSomething()).
It really depends on what you're trying to accomplish. If you have no else clause then if(!doSomething()) seems fine. However, if you have
if(!doSomething()) {
...
}
else {
// do something else
}
I'd probably reverse that logic to remove the ! operator and make the if clause slightly more clear.
As a general statement, its good to make your if conditionals as readable as possible. For your example, using ! is ok. the problem is when things look like
if ((a.b && c.d.e) || !f)
you might want to do something like
bool isOk = a.b;
bool isStillOk = c.d.e
bool alternateOk = !f
then your if statement is simplified to
if ( (isOk && isStillOk) || alternateOk)
It just makes the code more readable. And if you have to debug, you can debug the isOk set of vars instead of having to dig through the variables in scope. It is also helpful for dealing with NPEs -- breaking code out into simpler chunks is always good.
No, there is absolutely nothing wrong with using the ! operator in if..then..else statements.
The naming of variables, and in your example, methods is what is important. If you are using:
if(!isPerson()) { ... } // Nothing wrong with this
However:
if(!balloons()) { ... } // method is named badly
It all comes down to readability. Always aim for what is the most readable and you won't go wrong. Always try to keep your code continuous as well, for instance, look at Bill the Lizards answer.
In general, ! is a perfectly good and readable boolean logic operator. No reason not to use it unless you're simplifying by removing double negatives or applying Morgan's law.
!(!A) = A
or
!(!A | !B) = A & B
As a rule of thumb, keep the signature of your boolean return methods mnemonic and in line with convention. The problem with the scenario that #hvgotcodes proposes is that of course a.b and c.d.e are not very friendly examples to begin with. Suppose you have a Flight and a Seat class for a flight booking application. Then the condition for booking a flight could perfectly be something like
if(flight.isActive() && !seat.isTaken())
{
//book the seat
}
This perfectly readable and understandable code. You could re-define your boolean logic for the Seat class and rephrase the condition to this, though.
if(flight.isActive() && seat.isVacant())
{
//book the seat
}
Thus removing the ! operator if it really bothers you, but you'll see that it all depends on what your boolean methods mean.
try like this
if (!(a | b)) {
//blahblah
}
It's same with
if (a | b) {}
else {
// blahblah
}
I never heard of this one before.
How is
if (doSomething()) {
} else {
// blah
}
better than
if (!doSomething()) {
// blah
}
The later is more clear and concise.
Besides the ! operator can appear in complex conditions such as (!a || b). How do you avoid it then?
Use the ! operator when you need.
It is generally not a bad idea to avoid the !-operator if you have the choice. One simple reason is that it can be a source of errors, because it is possible to overlook it. More readable can be: if(conditionA==false) in some cases. This mainly plays a role if you skip the else part.
If you have an else-block anyway you should not use the negation in the if-condition.
Except for composed-conditions like this:
if(!isA() && isB() && !isNotC())
Here you have to use some sort of negation to get the desired logic.
In this case, what really is worth thinking about is the naming of the functions or variables.
Try to name them so you can often use them in simple conditions without negation.
In this case you should think about the logic of isNotC() and if it could be replaced by a method isC() if it makes sense.
Finally your example has another problem when it comes to readability which is even more serious than the question whether to use negation or not: Does the reader of the code really knows when doSomething() returns true and when false?
If it was false was it done anyway? This is a very common problem, which ends in the reader trying to find out what the return values of functions really mean.
I think a good example of a case of when to use if (!doSomething()) would be using Optional before Java 11. Java 11 added isEmpty, but before that there was only isPresent. Image you are trying to return early from a function ( a common programming best practice)
if (!option.isPresent()){
return -1;
}
would be a very common practice. Alternatively you could introduce a temporary variable yourself if you really want to avoid the ! inside the if
var isEmpty = !option.isPresent();
if (isEmpty){
return -1;
}
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
}
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;