Softer Software: How I improved the quality of my code

  • Some backstory of my dev experience
  • Patterns I noticed in my software
  • Steps to improve
  • Robert Martin’s Clean Code
  • Martin Fowler’s Refactoring

I entered software engineering in a less common fashion, I started working in the industry as a data analyst writing SQL. After 4 months on the job, I realised I could have the most impact by filling in a gap that few others seemed to be filling around me, by developing my technical skills with SQL. After enough difficult SQL problem solving, I naturally started to see other problems we could solve, by using skills which lay outside the core competencies of our team, so I started to teach myself how to write scripts and programs, using more object-oriented paradigms.

I mainly used node.js and python, but was interested in other languages. Unfortunately though, because of the way my role had evolved into existence, I didn’t have many people close to me that I could ask for help around code review, quality, and design. On the one hand, I was very tenacious, so with enough willpower and time, I was able to do most things I could imagine that we needed. But on the other hand, this sometimes left me without guidance on low level stuff.

Then end result was, that I could write a piece of software easily enough, but I found that if I came back to it in 4 months time, it took longer than expected to be able to understand how I had put things together. For over a year, I was trying on my own to just think in my head “don’t write this badly, try to take a little time and do it well”. Unfortunately, I found myself still looking back on recent projects, and criticising them for being inadequate.

Obviously my common-sense rationale wasn’t working, and no-one was telling me any better. (As a side-note, I recently started reading the mythical man month, which provides a few fantastic examples of how seemingly common sense actions can actually be the completely wrong decisions). So I decided to read up on how to write better code. A quick search on a few reddit boards points me to some highly recommended books, so I went with Robert Martin’s Clean Code.

I’ve executed plenty of ideas for self improvement, but reading this book was by far one of the best. It starts with a clear rationale that sets the tone for why writing clean code is important. In today’s fast paced business environments, young software professionals are often pushed to cut corners for the sake of meeting a deadline, but the author points out the potential for cost of cutting quality in software. It’s a programmer’s professional duty to treat their work as any other professional would. One of the analogies that stuck with me, which I’ve repeated many times since, is this: “you wouldn’t demand that your dentist stops washing their hands to save time. They use their professional judgement and say no”. Sometimes it’s not totally clear cut, you can’t just say no to your superiors whenever you please, but I found this book to be full of plenty of good rules of thumb.

There were a lot of practicalities contained here, and comparisons of realistic but poor code, to how it could be a lot easier for humans to read. Each chapter has a little quote, and while all of them are decent, some will likely stick in your head. One for me (which I’ve paraphrased) was:

“Clean Code should be boring. When I name a class, or a function, that name should make it very obvious what will be contained within. When I come to read that function, I shouldn’t be surprised by what I find.”

That’s one that I’ve lived by for a while, that I’ve found to be beneficial. The topics I found to all be incredibly useful, providing great insight into how to make code a lot easier to understand.

The chapter on naming things now has me regularly using my IDE to rename symbols as soon as I find a better name. The guidance on functions helped me form a good rule of thumb around what a good function looks like. One piece of advice I’ve passed on many times, is that a function should execute steps at a single layer of abstraction. Consider a process for sending a billing email:

  • we need to find all items in the order
  • check stock levels
  • reduce available stock
  • iterate over all items to find total value
  • get customer contact details
  • format email
  • send email

There’s no reason this can’t be one function, but the advice in the book laid out why it’s a bad idea — from the perspective of the programmer having to jump between low level string manipulation for formatting, to higher-level actions like send email, is mentally jarring for the programmer. This one has been fantastic for me to show others, when they have the feeling that their code isn’t great, but can’t quite put their finger on why they don’t like it.

Sections on comments helped me form opinions about when to remove comments — this was super useful in helping me rename things as well. Often times a comment explaining something in the code, can be replaced with a function, whose name is very close to the comment.

Other chapters on error handling, formatting, and testing, I found to be invaluable moving forward. What I found over the next few months, is that I shortly developed an intuition for writing code like this a lot closer to the first time. I refactored code very shortly after being written to be more in line with the principles I had learned. I got tons of value out of this book, and wouldn’t hesitate to read it for a third time!

After a few years of writing software that I was happy with from a quality standpoint, I was now in a position of providing code reviews and mentorship to others, and giving practical code advice, which was usually well received. I had moved up the career ladder, and considered my ability to write decent software instrumental in that. I was able to articulate my viewpoints a lot more succinctly, and give a rationale for why one thing is better or worse than another, usually with the approach of making it easier to read and understand the software.

I recently wanted to visit this area again, and get a different perspective, and another reddit search found some recommendations for Martin Fowler’s Refactoring, which was pretty well rated on Amazon — 78% of people, (over 250) rated it 5 stars, so figured this must have some value in it.

This isn’t a particularly bad book, but it didn’t quite provide what I was expecting. The back of the book promises the following:

  • understand general principles of refactoring
  • apply useful refactorings
  • recognise bad smells
  • explore refactoring, with explanations and motivations
  • build solid test for refactorings
  • recognise tradeoffs and obstacles to refactoring.

Now some of these points are well ticked, the general principles of refactoring, and a rationale for why this is a great idea are clearly presented. The importance of tests and how they’re closely intertwined with refactoring are well explained. If you’re trying to articulate to a manager or someone in charge at your organisation, how and why you should refactor, the first 4 chapters, in around 100 pages, cover this pretty well. Some of it is similarly covered in Clean Code, but this provides a good alternative perspective.

However, when it comes to the refactorings, I had a few things about this that I enjoyed less.

  • Some of these were incredibly trivial. I hadn’t seen someone take 3 pages of text to discuss how to rename a variable before, but I don’t think that was time well spent
  • Some of the examples are quite contrived — anyone trying to write reasonable software to begin with, wouldn’t ever have written these poor examples to begin with
  • A lot of these refactorings demonstrate each of the steps you might walk through while performing that refactoring by hand. At first, this is an odd process, like watching change code in slow motion, and it’s quite interesting and novel. But this quickly becomes a little tedious as the book is quickly filled up with lots of duplicate chunks of code with small changes between each successive reprint.
  • The book goes through in great detail, each step to perform a refactoring, but in practice, you’d simply ask your IDE to execute this for you, drastically shortening the time. (You might say “but you don’t always have an IDE” — but the author is explaining concepts and making it clear that he’s working in an IDE.)
  • The content of refactoring is not well presented in book format. I found myself thinking a few times, this book would be better shown as a series of github diff screenshots with comments. I recalled that the book said the canonical version of this edition was on the web. I tried that out, but was disappointed to see that it’s just the book on a webpage, with no better format for the material.

Although the book description talks about testing, this is basically a short chapter saying “Testing is important for refactoring and here’s why you should do it, but it’s out of scope”. The bad smells are quite reasonable, but I didn’t feel these were quite as well explained as in clean code.

I think I was expecting more of a tour of refactoring larger sections of applications, with a focus on strategy at a higher level of a codebase, practicalities of refactoring the supporting codebase of a product, and what that looks like. Some case studies around refactoring processes within organisations would have been great — with comparisons of large scale re-writes, versus incremental refactorings.

Unfortunately, this book was very low-level, focusing on optimising the particulars of a few abstract methods, in a much larger hidden application. I think for it’s purposes, clean code was a lot better.

I think it’s well worth investing time into reading books like these, they definitely have a valuable return, and although I didn’t like everything in Refactoring, it was certainly thought provoking and make me rationalise why I held certain beliefs about code I write. I’ve expanded my knowledge and experience reading books like these, and I feel it makes me a better professional — I’d recommend Clean Code quickly to anyone new to the software development industry.

Enjoyed this? My next article will be about the practicalities of date-sharded vs. partitioned tables in bigquery, and will be out by 24th Jan. Follow me and it should crop up somewhere, maybe in your emails or while browsing medium or something.