If you’ve ever worked on a development team, or even looked back at some of your old code, there’s probably a chance you came across a certain block of code that looked like someone had a fight on a keyboard while the text editor was open. Messy syntax, unclear variable definitions, and jumbled, cramped code can be a pain to read through — not to mention a nightmare when you’re pushing deadlines and are tasked with sorting through someone else’s sloppy code. So spending some time and learning to keep your code neat, concise, and easy to read is well worth it. Sometimes it can just flow as you’re coding and thinking at the same time, but nothing stops you from going back and cleaning it up once the code works. With a bit of practice, writing clean code will come naturally (and your coworkers will thank you for it), so here are 10 tips I’ve found that can help keep you from being that programmer.
Using a naming convention is a great way to get started — it keeps things clear and lets you know exactly what you’re working with. It also means you won’t accidentally try to use a string of text in a math equation.
A naming convention basically means you decide you’ll call your variables by names that adhere to a certain set of rules. There are preset rules I could go into, but it can get hairy, and a lot of people don’t always agree on which is best. So to keep it simple, just make it as clear as possible what type of variable it is, and keep naming consistent. It can be something as simple as prefixing variable names with their data type, like this:
2. 360 No Scope
The next thing, which follows nicely from using naming conventions, is using a convention to indicate variable scope. Again, there are no rules, and everyone has their own way of doing it — as long as it’s consistent throughout all of your code, it will always be clear what can be used from where.
A common convention, and the one I use myself, goes as follows:
Again, feel free to write things differently if you prefer it that way — the most important thing is to have a clear and consistent style. If someone else is looking at your code, they shouldn’t be caught by things not being as they expected.
3. Say What You Mean
This is pretty straightforward, but it’s probably the most common thing I see and maybe the easiest one to forget. Easily the most frustrating thing for another developer looking at your code is seeing a variable with a misleading name or, worse, named with a single letter. The names you give your variables and functions are incredibly important — it should leave the reader with absolutely no doubt what the variable is used for or what the function does.
Let’s take a look at an example of this:
While this might look okay, and it is functional, if someone found this in a sea of code with no comments, it isn’t clear why any of it is happening at all. And someone shouldn’t have to read the function’s contents to know what it does.
Here, the user has no idea what n will be and no idea what max is. Although this depends a little on your program’s architecture, if you’re returning something to indicate a boolean value (true/false or yes/no), then you should return a boolean, not a number.
So here’s how we can clean it up:
Now we immediately know why the evaluation is being made, we know what is being checked, we see the player’s health is being passed in as an argument, and we see it is being checked against the maximum health. We are also now returning a boolean value, which allows us to clean up the syntax of the function by directly returning the result of the evaluation. But most importantly, we don’t need to read any of that, as we can see the function is checking to see if the player has taken damage by its name.
4. Whitespace Is Nice Space
Often I see people writing bunched-up, smashed-together code, leaving no space anywhere. What does this result in? Code that’s really hard to read. Our eyes don’t like solid walls of text, which is why we’re taught to break words up into paragraphs in school — the same theory applies here.
So, in general, if you’re writing lots of things together in one block, and then try to separate the code chunks into logical pieces, maybe have all of your code that positions some text fields, then a line of whitespace, and then write another chunk where you assign them all a value. Things like this might seem annoying at the time of writing, but are crucial when trying to quickly find something in a large section of unfamiliar code.
5. Commenting Saves Lives — or At Least Headaches
Adding comments to your code can be invaluable — they can quickly show what a complex function is doing, or maybe even explain why certain things need to happen in a certain order. They do have a downside, though, because too much commenting can have the opposite effect and actually make for messier code.
Let’s look at the following example:
These comments are out of control and are actually all completely unnecessary. Comments should be used only when they are needed to describe functionality, or perhaps to remind other programmers of information they otherwise would not have access to at that point.
6. Automate After 3 Times
Writing slightly more technical code doesn’t mean it has to be less readable. Lines and lines of duplicate code are not only harder to read than a concise and elegant solution, but also increase the chance for error. The great thing about programming is that you can express complex commands in tidy, reusable, and clever ways.
So, let’s take a look at an example of poor, duplicated code:
And here’s an approach that cleans everything up:
This approach is not only tidier but is a much more eloquent solution. And now if I want to add another evenly spaced box, I just need to add another box to the array, allowing the loop by default to loop once more as it checks the size of the array.
7. The Power of i
This is a small tip but follows on directly from the previous concept. When you have a code block with multiple loops one after the other, you need different iterator variables. There is always debate about what to use, and the answer is slightly subjective, but when they’re one after another, it makes sense to declare your iterator outside of the loop and reuse it. It’s not only better to look at, as it’s always clear that “i” is your iterator variable, but it’s also slightly more efficient.
Let’s look at an example of what I’m talking about:
But what about when I said not to use one-letter variable names? In this case, it simply makes sense to, and if your loop iterators are the only variables with single-letter names, then it isn’t an error, it’s a convention.
8. Birds of a Feather Flock Together (and They Group Similar Variables)
When your projects start to get larger, your classes will likely have many variables. First, you should be keeping all of your variable declarations at the top of the page, or at the very least all together somewhere — this speeds up any kind of searching when you need to find something.
Second, even though they are all together, it often helps to arrange them in such a way that makes them even easier to comprehend. For example, grouping them all by what they are is a good way to go. It’s quite likely that you’ll have several types of the same object, so keep those all together in groups, and then maybe have a section for the miscellaneous ones underneath.
9. Keep It Functional
Mile-long function definitions are an easy way to clutter your code. Normally it’s best to take a look at what’s actually being done. If a function is doing more than its name suggests, then perhaps some of the excess functionality could be split out into its own function. This can often help the rest of your code, too, because it becomes easier to look at. And if smaller functional chunks can be used on their own, then it means other parts of your code can use them without the need to duplicate code.
For example, let’s say you have a function that creates a sorted list of objects that share the same state. It might be a good idea to create a separate function that simply compares the states of two objects and indicates if they’re the same or not. You can then call this function from within your sorting function, and it means the comparison code is open to be used elsewhere, which, in this case, is quite likely.
10. Keep It Classy
Similar to the functional problem, if there’s a large amount of functionality you’re keeping all in one place, it could be better to create a separate class just to handle that functionality. Again, this is all about reusability and keeping your programming tidy — maybe some other classes are using the same functionality, so wouldn’t it be better if, instead, they all accessed a single place that was handling all of these things?
A good example might be when classes are all loading in resources themselves — the code can be messy, and if you want to change how resources are managed, you have to change it everywhere. In this case, creating a ResourceManager class with a getResourceByName() function could be a clean and elegant way to make that functionality a bit classier.
These are just a few different ways to clean up your code — they’re not concrete rules and, of course, you’ll find your own style and way of doing things. Just remember to keep it tidy, clearly sectioned, and consistent. Anyone working with your code will appreciate the effort, and might even learn something from your example.