开发者

Using Return Stylishly

Let's say I had a lot of code between an if statement. Is it more proper to do a quick if-else check before it, and if it fails, return.

OR create the if statement with a lot of code in-between but not use return?

OR is it just a matter of preference?

so my 2 options are: if(!something){ return } els开发者_如何学Goe //lots of code here

if(something){ //lots of code here }


From a performance perspective, you should always return from a function as quickly as you can, avoid doing unnecessary computations, "short-circuit" if you will. So checking for error cases and returning quickly would be the better policy.

Edit to add: In the same vein, you should always check the cases that are most likely to be violated first, this is sound advice when structuring your conditionals as well (|| and && checks)


I think this looks much nicer:

func() {
   if(someCondition) {
      return;
   }

   if(otherCondition) {
      return;
   }

   //lots of code
}

than this:

func() {
   if(someCondition) {
      return;
   } else if(otherCondition) {
      return;
   } else {
      //lots of code
   }
}

or this:

func() {
   if(!someCondition) {
      if(!otherCondition) {
         //lots of code
      }
   }
}

It looks even uglier with more conditions, so I generally use the first method.


I prefer "shortcut". It has nothing to do with performance, as modern computer can handle if-else very fast, so we should focus on code readability.

However, if there's so many if-else in code, you may re-think your design. Refactory can be a better choice.


Readability and performance are not necessary conflicting constraints but when they are I tend to give readability the front seat.

To enhance readability I tend to follow the following rules.

Rule 1. Keep return as the last line of code, whatever comes in the middle. In other words don't sprinkle return statements whenever you want just because you're not too sure your if-else structure will cascade down just before the final return.

Except may be for the simplest methods I privilege a structure like

MyType func() {
    MyType result ;
    if ( condition ) {
        result = result_1 ;
    } else {
        result = result_2 ;
    }
    return result ;
}

over an allegedly simpler

MyType func() {
    if ( condition ) {
        return result_1 ;
    } else {
        return result_2 ;
    }
}

In my opinion the performance cost, if any, is negligible. However, when scaled up, I find the first coding pattern much more readable.

Rule 2. Refrain from starting a logic by "evacuating" error conditions, just in order to get them out of the way and free your mind. If your logic is well thought these checks will find their place in the logic (also have a look at guava for many well though techniques of encapsulating routine checks in helpers).

Many freshmen in my team start coding things like this

MyType func (ArgType arg1,...) {
    if ( arg1 == null ) {
        throw new Exception ( "hey dummy, we don't take null arg1) ;
        // or return null ;
        }
    if ( arg2 == null ) {
        // you got the picture...
        }
    // wow at last !!! all checks done
    // Combine args and return result...
}

Which I have to say, is already a progress on just taking all conditions for granted

I tend to prefer

MyType func (ArgType arg1,...) {
    MyType result ;
    if ( try_to_compact_all_checks_here ) {
        // Combine args and return result...
    } else {
        // throw, log, nullify result etc
    }
    return result ;
}

If the condition "try_to_compact_all_checks_here" does not fit in one line, I even sometimes prefer to get out of my way and I encapsulate all the checks in a private function. Even if it's called only once.

Rule 3. Keep the number of lines in an if/else statement to a reasonable amount (basically should fit on one screen in your IDE). To do so it is sometimes possible to extract some logic and stick it into a private function. No problem at all. All modern IDE do that for you in 2 clicks.

So basically the previous template becomes.

MyType func (ArgType arg1,...) {
    MyType result ;
    if ( checks_here ) {
        // 1 to 20 lines max, 
        encapsulate lengthy logic in full fledged private methods.
    } else {
        // throw, log, nullify result etc
    }
    return result ;
}

Rule 4. Inner IFs should always have an ELSE, and that ELSE should be different from the outer ELSE.

Explanation: If I end up with

MyType func (ArgType arg1,...) {
    MyType result ;
    if ( check_1 ) {
        if (check_2) {
           Do the real work
        } else {
           treat error condition
        }
    } else {
        same error condition as above
    }
    return result ;
}

Then it's probably because my check analysis is not complete. It happens quite often.
I try to reach

MyType func (ArgType arg1,...) {
    MyType result ;
    if ( check_1 && check_2) {
        Do the real work
    } else {
        same error condition as above
    }
    return result ;
}

That's all.
I found that, by observing this kind of conventions, I can process large Java projects with ofter complex business logics (like in ESBs, Web Services etc), at very little performance cost if any.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜