This is a subjective post on what I consider good practices for writing functions (or methods in an OO language like Java). I’m aware that functions are OO languages are technically “methods” but I’m going to use the term “function” for simplicity.
1. Atomic Functions
It started many years ago in uni when a requirement for an assignment was that our functions must not be longer than 20 lines, or else we’d lose marks. The idea was to split up the functions if they exceeded 20 lines. Yes, keeping functions as short as possible can help to reduce confusion and aids with maintenance. But the most important thing is not the length, but to have the function do as little as possible (not a bit of this and a bit of that, but one thing). I don’t think that putting an arbitrary limit on function length is particularly helpful. By the way, in a later uni project, having “learnt” from the previous assignment I split all my functions up so each was tiny – then I lost marks for having too many small functions! Well…that’s uni for you.
2. Descriptive Function Names
Not many argue that a function signature such as incIdx(v) is helpful to anyone – it’s too cryptic. But how about getProducts()? It’s better and will suffice in a compiled language such as Java where the IDE will show the return type. However in an interpreted language such as PHP, it’s not that great unless you use PHPdoc so the IDE will tell you what it expects for the return type, otherwise you have to look in the function to see what it returns.
What if you need a function that returns a product based on the parameter you pass to it? You can pass getProductBy(name) or getProductBy(price). In a language that allows for method overloading, you should make use it of. In a language without method loading, I feel it’s fine to write multiple functions like: getProductByName(name) or getProductByPrice(price). Of course don’t forget PHPDoc. Some people might write getProductBy(value, by) and do a sequence of if/else statements inside the function and use the parameter “type” to determine what to retrieve – but I think that’s unnecessarily confusing.
3. Organizing Functions
Usually I prefer to group functions by relationship first, then by alphabetical order inside of those groups. Only doing it alphabetically isn’t really helpful unless you have a photographic memory and remember the names of each function.
4. Returning Early
I actually read about this on www.debuggable.com quite a while ago. To anyone but beginner programmers this concept is so deeply ingrained, but when I was first getting into coding years back I was confused to see 2 or more returns within a function. Then I discovered how ridiculously simple it all was – when a function encounters a return, it returns the value and the function quits at that point. It returns the value obviously, but most importantly it returns control to the code that called it. You will often have multiple returns in a function, each return within a conditional, and then you will have a default return in case none of the conditions were satisfied.
3. Replacing class variables with functions
There are times when you may want to replace class variables with functions to avoid duplicating data. I consider doing this when the value of a variable is completely dependent on 1 or more other variables. For example, if air pressure is completely dependent on the variable altitude (in reality air pressure is a function of altitude and temperature), then we could write a function getAirPressure() which calculates the air pressure based on the altitude and then returns it.