Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h1>You should <em>never</em> use a return statement in a method.</h1> <p>I know I will be jumped on for this, but I am serious.</p> <p>Return statements are basically a hangover from the procedural programming days. They are a form of goto, along with break, continue, if, switch/case, while, for, yield and some other statements and the equivalents in most modern programming languages. </p> <p>Return statements effectively 'GOTO' the point where the function was called, assigning a variable in that scope.</p> <p>Return statements are what I call a 'Convenient Nightmare'. They seem to get things done quickly, but cause massive maintenance headaches down the line.</p> <h1>Return statements are diametrically opposed to Encapsulation</h1> <p>This is the most important and fundamental concept of object oriented programming. It is the raison d'etre of OOP.</p> <p>Whenever you return anything from a method, you are basically 'leaking' state information from the object. It doesn't matter if your state has changed or not, nor whether this information comes from other objects - it makes no difference to the caller. What this does is allow an object's behaviour to be outside of the object - breaking encapsulation. It allows the caller to start manipulating the object in ways that lead to fragile designs.</p> <h1>LoD is your friend</h1> <p>I recommend any developer to read about the <a href="http://en.wikipedia.org/wiki/Law_of_Demeter" rel="nofollow noreferrer">Law of Demeter</a> (LoD) on c2.com or Wikipedia. LoD is a design philosophy that has been used at places that have real 'mission-critical' software constraints in the literal sense, like the JPL. It has been shown to reduce the amount of bugs in code and improve flexibility.</p> <p>There has an excellent analogy based on walking a dog. When you walk a dog, you do not physically grab hold of its legs and move them such that the dog walks. You command the dog to walk and it takes care of it's own legs. A return statement in this analogy is equivalent to the dog letting you grab hold of its legs.</p> <h1>Only talk to your immediate friends:</h1> <ol> <li>arguments of the function you are in,</li> <li>your own attributes,</li> <li>any objects you created within the function</li> </ol> <p>You will notice that none of these require a return statement. You might think the constructor is a return, and you are on to something. Actually the return is from the memory allocator. The constructor just sets what is in the memory. This is OK so long as the encapsulation of that new object is OK, because, as you made it, you have full control over it - no-one else can break it. </p> <p>Accessing attributes of other objects is right out. Getters are out (but you knew they were bad already, right?). Setters are OK, but it is better to use constructors. Inheritance is bad - when you inherit from another class, any changes in that class can and probably will break you. Type sniffing is bad (Yes - LoD implies that Java/C++ style type based dispatch is incorrect - asking about type, even implicitly, <em>is</em> breaking encapsulation. Type is an implicit attribute of an object. Interfaces are The Right Thing).</p> <p>So why is this all a problem? Well, unless your universe is very different from mine, you spend a lot of time debugging code. You aren't writing code that you plan never to reuse. Your software requirements are changing, and that causes internal API/interface changes. Every time you have used a return statement you have introduced a very tricky dependency - methods returning anything are required to know about how whatever they return is going to be used - that is each and every case! As soon as the interface changes, on one end or the other, everything can break, and you are faced with a lengthy and tedious bug hunt.</p> <p>They really are an malignant cancer in your code, because once you start using them, they promote further use elsewhere (which is why you can often find returning method-chains amongst object systems).</p> <p>So what is the alternative?</p> <h1><em>Tell</em>, don't ask.</h1> <p>With OOP - the goal is to tell other objects what to do, and let them take care of it. So you have to forget the procedural ways of doing things. It's easy really - just never write return statements. There are much better ways of doing the same things:</p> <h1>There is nothing wrong with the return <em>concept</em>, but return <em>statements</em> are deeply flawed.</h1> <p>If you really need an answer back - use a call back. Pass in a data structure to be filled in, even. That way you keep the interfaces clean and open to change, and your whole system is less fragile and more adaptable. It does not slow your system down, in fact it can speed it up, in the same way as tail call optimisation does - except in this case, there is no tail call so you don't even have to waste time manipulating the stack with return values.</p> <p>If you follow these arguments, you will find there really is <em>never</em> a need for a return statement.</p> <p>If you follow these practices, I guarantee that pretty soon you will find that you are spending a lot less time hunting bugs, are adapting to requirement changes much more quickly, and having less problems understanding your own code.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload