Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Stretch the Old Rules, Please

DZone's Guide to

Stretch the Old Rules, Please

Here we examine the classic single point of exit rule to see how it fits into modern programming and consider a new way of thinking about it.

· Java Zone ·
Free Resource

Learn how to build stream processing applications in Java-includes reference application. Brought to you in partnership with Hazelcast.

In my programming career, I heard plenty discussions about single vs. multiple return statements in methods. In the past, I was sure that single exit was the only valid way, which led me to one return per method. Now, I still think that a single exit point is good, but the meaning of it is completely different for me.

In the original definition, which is "A function should have one point of entry and one point of exit," we have two hidden rules. In modern OOP languages like Java, it is hard to imagine that you can start your method from the middle, so the first rule is quite outdated (in older languages, you can use "goto" or something like "jump"), so we should cut this rule into "A function should have one point of exit."

Ok, so what is this "single point of exit?" Most programmers think that rule is saying that there is only one return statement, and I was in this group. We can easily point some advantages of this approach:

  • multiple returns are harder to read

  • fewer returns means less complexity

  • you can put a debugger breakpoint on one return at end of the method

  • some languages require a single point of exit (e.g. Pascal)

While the last argument is quite weak for me (as I mainly think in Java), the rest are very convincing. So from code like this:

public int getRealPersonAge() {
    if(this.type == MALE) {
        return this.age;
    }
    return 18;
}


I started refactoring my code to this:

public int getRealPersonAge() {
    int age;
    if(this.type == MALE) {
        age = this.age;
    } else {
        age = 18;
    }
    return age;
}


Single exit, so we can be happy now.

BUT

Is it really better now? Is it easier to read? Is it less complex? These were my questions after each refactoring. But I was so blind about sticking to the rule that I silenced my inside voices without really thinking about it. Then after a few months, when I got more experience in coding, I started to be more elastic in my coding standards.

Of course, the first code will be always clearer and less complex, even if there are three or four returns. The biggest problem with readability is not the number of return statements, but the lines of code (LOC) in the method. Imagine, a 200 LOC method with three return statements, first in line 10, second in line 130, and the last in line 200.

Is that a problem with the three return statements? Or is it with the complexity of the method? Then imagine a small method (for me, a good method has max 10 LOC) with the same number of return statements. The smaller method is more readable and, even with multiple returns, it will be still easier to test and maintain. Everyone can look at it and know what is going on.

But returning to rule — finally, I discovered that even for one return value, this rule can be not valid:

public Person getUpdatedPerson(Person person, Person person2) {
    person.setName(person2.getName());
    person.setAge(person2.getAge());
    return person;
}


What do you think about this code (besides the poor complexity of my use case)? How many return statements and exit points does it have? From an API view, we should expect that person will be not updated, but copied into a new instance and returned, but in this situation, it will not occur. We have TWO points of exit — one by return statement and second by the parameter. In this situation, to put it into the single exit point rule, we should write:

public void updatePerson(Person person, Person person2) {
    person.setName(person2.getName());
    person.setAge(person2.getAge());
}


OR

public Person getUpdatedPerson(Person person, Person person2) {
    Person newPerson = new Person();
    newPerson.setProperties(person.getProperties());
    newPerson.setName(person2.getName());
    newPerson.setAge(person2.getAge());
    return person;
}


Again, as you can see, the problem here is not the number of return statements, but what an exit point is from a user view of the object's API.

Multiple return statements are not evil at all. You can use them in a situation when they will be more readable (check the first code block in this post). In my opinion, they are not breaking the rule of single exit points.

In my understanding, the single point of exit nowadays in Java is applied to "returning" by return statement or by parameters, not by the number of return statements itself. So one exit point should be rewritten to one exit point type, which can be "return" statements (one or multiple) or by modification of entry parameters.

The biggest issue with that is that programmers write unnecessarily long code, do not divide big methods into smaller ones, and create trouble-making, complicated contracts in their APIs. In the present world of OOP languages with Garbage Collection and without ugly "gotos" or explicit "jumps", we should rewrite some old programming rules.

Learn how to build distributed stream processing applications in Java that elastically scale to meet demand- includes reference application.  Brought to you in partnership with Hazelcast.

Topics:
java ,code style ,single point of exit ,clean code

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}