Mastering the Art of Creating Unbreakable Code

The bad news...

Back when I was a student, I used to see posters around campus that said things like “FREE BEER! Now that I have your attention, please remember to return your library books before the Christmas break”. I used to really hate those…

The bad news is that you can’t really write unbreakable code. But there are some things that you can do as a software engineer to make your code less breakable… less buggy, more reliable etc. In this post I will briefly describe some of these techniques and if nothing else you will leave more likely to remember to return your library books before the Christmas break.

Reduce complexity

website-tech-coding03 2

This is at the root of it all – most of what follows are just different ways of reducing complexity. But why is reducing complexity important? It’s actually pretty obvious because its everywhere – we are human and humans are fallible. We make mistakes. We tend to make mistakes more when things are harder to do, ie more complex. Computers don’t make mistakes, they just do what we tell them. So it is upon us to correctly tell computers what to do and for us to do that reliably we need to make things nice and simple for ourselves.

There is no real skill needed to place a ball on the floor, but to balance a ball on your nose… that takes lots of skill, balance and practice. If you were set a task that could only be achieved by balancing a ball it would be a wise decision to balance it on the floor rather than your nose. Less complex. Less can go wrong.

Writing software is never going to be as easy as placing a ball on the floor, but the process will be made up of many small decisions where you can choose to simplify things, or not. Often the most obvious choice will be the one that eventually becomes complex, so you need to consciously choose the route of simplicity and you need to do that over and over and often it may seem like more work. Some complexity will end up living somewhere so its best that you choose where and try to reduce it as much as possible.

Readable code

website-tech-coding01 2

I was going to put this much further down the list but, like reducing complexity, it is at the heart of so much of what will follow.

Computers move data around as a series of zeros and ones. Languages like C# were not created for a computer’s benefit. They exist for us humans, to help us write code that we can understand. We are making an immediate mistake if the code that we write is not easily readable.

Is readable code just about the use of comments? No! Comments can be useful for setting context, but if the code itself is readable – by using function names, parameters, variables etc that are self-explanatory – then the need for comments mostly goes away.

The structure of the code is just as important. Breaking code down into small easy to understand chunks helps to make it readable. How do you do that? Well, you use techniques like…

Separation of concerns

Separation of concerns - i.e. the avoidance of co-locating different concerns within the design or code - is a core software design principle. If you properly separate concerns, then your software will be less tightly coupled and therefore easier to maintain. You will be less likely to duplicate code and you will be able to navigate and understand the code easier.

Modularity & cohesion

Code modularity is about breaking code down into separate building blocks that can be used by your applications. Modularity and separation of concerns go hand in hand - you separate concerns by breaking your code down into different modules.

Cohesion is about how much the different elements in a module belong together. If you have properly separated concerns in a module, then the elements in that module will belong together and cohesion will be high.

Small, cohesive modules of code are easier to understand and therefore easier to debug - code complexity is kept low.

Use of abstraction

Abstraction is about simplifying things by hiding unnecessary complexity. As is so often the case, a car analogy works  here - you can drive a car perfectly well without understanding how every individual component of a car works Similarly, one part of an application does not need to be intrinsically linked to another part of the application just to get what it needs - function b needs some data from function a, and as long as it gets the data it needs, then it works just fine. You shouldn't need a deep understanding of how function a works to understand function b

Avoid duplication

They ay that less is more. Clearly, this is nonsense because less is less, but having less code to maintain is an easy way to reduce complexity. Duplicating code does the opposite - it needlessly adds code and therefore complexity. If you duplicate some code seven times and then find a bug in it, you need to go to severn different places to fix that bug. Even navigating your code becomes harder when you duplicate the same code over and over. Avoid duplicating code, instead move the  code into its own function, properly abstracted, so that it can be used time and again (but remembering to keep concerns separated). 

Avoid long conditional statements

Long conditional statements are hard to read and are a good sign that you are duplicating code, failing to separate concerns...and probably ignoring most of the techniques above. If you find yourself writing a long conditional statement, then it is time to refactor that code!

Keep methods and functions short

If your functions are getting long, you should stop and ask yourself why. Are you properly using abstraction? Are you duplicating code? Are you using long conditional statements? Think of long functions as a warning sign that you are failing to keep things simple.

Designing before writing 

website-tech-coding02 2

All of that is a big ask right? Code evolves as you write it and before you know it you have painted yourself into a corner. So how do you avoid that?

Firstly, ask yourself this question – what is the primary role of a software engineer? Is it to write code? When you stop to think about it, software engineers are here to resolve a problem and that involves figuring out how you are going to solve the problem.

A best-selling author creates a story in their head. Writing it down is just the way that they share the story. A good software engineer creates the solution to the problem they are working on in their head. Writing lines of code just communicates that to the computer.

The way to ensure that you are using the techniques described above is that you plan to use them. You design and plan your solutions to make use of the techniques before to start to write any lines of code. And you constantly refactor your code, forcing yourself to adhere to the rules of simplicity. Has a method grown in size? Break it down! Ended up re-using a chunk of code three times? Move it into its own function!

Summary

So, what have we covered?

  • Code is never unbreakable, but by reducing complexity you can reduce the opportunities to make mistakes
  •  Making your code easy to read by use of self-explanatory function names etc and by writing code in small, tightly focused modules helps reduce complexity
  •  Duplicating code, use of long conditional statements and of long functions are all signs that you are making your code overly complex and harder to read
  •  Some up-front planning can help keep you on the path of producing simple code

Also, if you haven't already, check out Dave Farley's YouTube channel, where you will find well-reasoned explanations of much of the above and a lot more.

 

More from iVendi

 
Discover more about iVendi, read our resources and browse our knowledge base.
 

Tech Hub

Stay ahead of the curve with cutting-edge insights and resources.

Tech Blog

Discover the latest news and expert articles from iVendi Product & Tech.

Effective UX

Discover the importance of effective UX design.