As time’s passed, I’ve really begun to appreciate the short and sweet things in life. Short bus rides, instant payments and the time between a Google search and what ever it is I’m looking for.
Naturally, this appreciation has extended to the code I read and write. Short arguments, short methods and short classes. Can’t beat it.
Looking back on other people’s, and certainly my own, old code, I’m disgusted by what I call ‘foot-long functions’. These abominations are like reading chapters in a novel without paragraphs. Ideally, functions should do one thing and one thing only and, usually, when they do more it’s just plain wrong.
“James, why is it so wrong?” you might ask. Well, the list is potentially endless but here are my main gripes:
- Longer functions that handle more than one thing are harder to comprehend, thus harder to maintain.
- Limits the usage of the function.
- Disables my right to move the function to a new home.
You’re probably into web development so you probably also know that serving all your content into one, long block of text wouldn’t do your conversion rate any favours. This concept similarly applies to code.
Functions were introduced, in an imperative sense, as a means to split a program into smaller, commonly-used tasks. You may find you only need to use half a function. Don’t you dare add in that if conditional. Just split it into two functions!
Chances are, during a refactoring session, I may want to move a piece of code to a different class where it rightfully belongs. This process is made a lot smoother and more manageable when I can actually understand the code.
An argument against long function arguments.
I think everybody has been guilty of this in the past before realising their horrendous mistake. Without proper consideration, this kind of thing can really build up on you and it’s never pretty. Here’s why:
- Adding a new argument to a much used function makes any argument before it harder to remove later on.
- It is a sign that there is either:
- A lack of structure to the data and/or
- Your function is doing far too much
This problem is solved quite easily earlier on by using even the simplest of data structures. You can use arrays, hashmaps and objects. If the abstraction called for it, a parameter object would be beneficial. However, since I keep my functions short, they really only need 1 or 2 basic data types, with the second being an array.
In PHP, the above 3 data structures are available built right in and are used EVERYWHERE. Chances are your configuration file uses hashmaps.
Ever found a majority of those arguments are booleans? Use a bitmask. For example:
function get_listings($is_published, $is_featured, $is_frontpage)
Although that argument list isn’t THAT bad, it can easily be made shorter like so:
Where options has 1 bit per boolean option you wish to pass. You can then use bit-wise operators on these variables to set and get the individual booleans:
$options & 1 == $is_published $options & 2 == $is_featured $options & 4 == $is_front_page
And to set them:
$options = $options | 1; $options = $options | 2; $options = $options | 4;
As you can see, it’s quite simple to use. The integers you can use are in a 2n sequence. You probably know why this is but I’ll explain why anyway: bits are represented in binary. In the above example, there are a total of 3 bits being used and we are using each of those 3 bits as 3 booleans independent of each other rather than as a decimal value as a whole. 1 is 001, 2 is 010 and 4 is 100 and that same pattern continues as you progress up the sequence. It’s best to look past the literal value of 5 and think of the number as a series of switches when working with this.
As a quick note, I wouldn’t use literal integers with, I strongly recommend you define constants for this.
What about classes?
I’m beginning to notice that my code, along with a lot of other people’s, is not using the full power of object-oriented programming. I can see that a lot of libraries and applications, written on the CodeIgniter framework, only use classes as a means of organising procedural code. It makes for cleaner PHP but it’s still not quite OOP.
Who cares if you’re using instance variables? That’s just like using static global variables in C, which are limited to a source file in scope.
Who cares if you’re using stdClass? That’s the equivalent of a struct in C.
Who cares if you’re using an MVC framework? Yes, the framework is OO but the code written for it is definitely not.
Maybe CodeIgniter encourages this sort of coding. It’s not very often you see a class defined as a type of object, rather just a group of related methods. Not once in my time working with CodeIgniter have I seen an object being used the way objects were intended to be used.
I’m guessing the above won’t change soon though and shows more my concern at what I’m becoming and what other CodeIgniters are currently doing.