CleanCode

Code as a means of knowledge exchange


The dictionary defines the word Code as: “a system of words, letters, figures, or symbols used to represent others, especially for the purposes of secrecy.” Hopefully when I write software my code lacks secrecy!

Lately I’m becoming far more aware of how code works as a form of communication. I’m looking at code and considering how well it gets across its intent. One issue with code is that it has to communicate at different levels, it has to communicate with the programmer who writes it (Original coder), the programmer(s) who read it (Maintainers) and the compiler.

Original coder - has the benefit of knowing the context it fits into; if they are lucky they will know all of the code that surrounds it and have a thorough understanding of the problem it is trying to solve. This can be an issue as when they understand everything so well they can easily neglect to get that understanding across in the code they write.

Maintainers - could be the original writer and remember the code does and why although if it’s several months later what they remember will fade (unless they have exceedingly good memories – I know a couple of people like this and I am thoroughly jealous!). If the reader was not the original writer then they must rely on what they can gather from the code itself to help them understand what it does; unless the original coder was good at communicating their intent then this can be a difficult and time consuming task. Documentation can help this process but can also hinder it by not being up to date or simply conveying different information than the code itself.

Compiler - has the easiest job as it usually has a very strict set of rules that must be adhered to and if you don’t write code according to those rules you can’t compile (assuming we’re using a compiled language!). It is of course still possible to write code that doesn’t run very well but that’s a little off topic for this post!

Communication for people is a very hit and miss affair, you can talk to a room full of people and some will understand what you say and others won’t. The same can happen in written code.

So how do you write code that will help people to understand your intent when you write it?

Be verbose with EVERYTHING, for example if you want to store the count of a number of pages, call it PageCount, don’t call it X or even Count. If you’ve already got a collection called Pages then Pages.Count will convey the same thing. The same goes for method names, parameter names, class names, everything! In particular try to keep things named the way you would say them, for example the sentence “If the users requires the document then generate it and send it to their email address”, would become:

If (user.RequiresDocument)
{
		Document document = GenerateDocument();
		Email.Send(document, user.EmailAddress);
}    

You can see that a lot of the words from the sentence are actually in the code.

Keep things small to keep them simple to understand. Small can be subjective, for me:

  • a method is getting too big with 40+ lines of code
  • a method signature is too long with 5+ parameters
  • a class is getting too big with 300+ lines of code

Here when I say lines of code I include white space and lines with just braces on them. The above are of course vague and there are exceptions. I think a lot of this is driven by the Single Responsibility Principle, so if something is getting too big and complicated then it’s unlikely to be doing just one thing. This is also driven by a standard approach to problem solving i.e. if you’ve got a complex problem then split it up into smaller problems and at some point those problems will become small enough for our tiny minds to be able to handle!

Keep things familiar – if the code follows existing patterns that developers are already familiar with then they will find it much easier to read. A good analogy of this is when a non-English speaker converses in English, if they aren’t that fluent in English then they may put words in the wrong order, use incorrect grammar or pronounce words incorrectly. All of this makes it harder to understand because it doesn’t follow the patterns that you expect. The same thing happens in code. That’s why it is good to use naming conventions (for example the name of an interface should always start with a capital I), follow other coding guidelines (for example one class per code file) and applying Design patterns (such as the Factory Pattern).

A couple of other things I feel are important:

  • Be careful if you find yourself writing lot of comments, a lot of the need for comments can be removed by simply naming variables and methods well, they act as a description of what’s going on.
  • When writing tests hold the same values as you do for other code – If someone breaks a test written by another programmer and then can’t easily understand what the test was trying to do then they’ll waste a lot of time. I’ve been here many times!

Further reading that I found useful writing this article:
http://chrismm.com/blog/how-to-reduce-the-cognitive-load-of-your-code/
https://codeblog.jonskeet.uk/2013/09/21/career-and-skills-advice/


Got a comment or correction (I’m not perfect) for this post? Please leave a comment below.
You've successfully subscribed to Gavin Johnson-Lynn!




My Pluralsight Courses: (Get a free Pluaralsight trial)

API Security with the OWASP API Security Top 10

OWASP Top 10: What's New

OWASP Top 10: API Security Playbook

Secure Coding with OWASP in ASP.Net Core 6

Secure Coding: Broken Access Control

Python Secure Coding Playbook