Is the software development industry trapped in a cycle of being ‘perpetually immature’?

A while back an xkcd comic on Voting Software attracted a lot of attention on Twitter for it’s alarmist comparison of the attitudes of the software development industry to other engineering disciplines and in particular, this statement:

“our entire field is bad at what we do, and if you rely on us, everyone will die”

From: https://www.xkcd.com/2030/
Voting Software
From: https://www.xkcd.com/2030/

This was widely shared and quoted on Twitter, and even shared by industry leaders such as Grady Booch:

https://twitter.com/Grady_Booch/status/1027291830101016576

There was one comment in reply to Booch’s tweet that particularly resonated with me:

https://twitter.com/Joerg1968/status/1027417862422573057

“I fear that perpetual adolscence is our curse and our gift – (we’re) always chasing the next shiny thing”

Joerg Muller-Kindt

This thought that as an industry we’re stuck in “perpetual adolescence” caught my attention. As an industry we struggle to advance. What’s unusual when you think back over the past 20 years and even further back looking at the history of our industry, there are developments and ‘movements’ where groups of individuals come together to champion an idea that at first seems to make a positive improvement to our industry as a whole, and then over a few more years the ideas fade away and seem to be forgotten. Some are even occasionally rediscovered again by another group of like-minded individuals years later.

The ‘perpetual adolescence’ of our industry as I see it is not that we’re stuck at a particular point in our industry’s growth and unable to progress, we do progress and advance. This growth however, appears to be in short cycles where we move forward, but then we go back to what we were doing before, and we’re stuck in a cycle of discovery and rediscovery. It’s not as bad as one step forward, two steps back, but it does appear to be something like one step forward, one step back. We’re never continually advancing, occasionally we move forward but we end up going backwards again. The progress of our industry never seems to be continually moving forward. Maybe this is typical of any industry in its infancy.

Examples:

  • The ‘software crisis‘ of the 1970s
  • Structured Analysis and Structured Design
  • Formal methods
  • 4GL development tools focused on developing specific styles of application (e.g. PowerBuilder, and client/server type systems)
  • The hype of Object Oriented languages
  • Fred Brooks seminal article “No Silver Bullet
  • CASE (Computer Aided Software Engineering) tools and code generation – mid 1990s
  • UML, Rational Unified Process (RUP)
  • The Agile Manifesto
  • The cycle of centralized vs decentralized (distributed) systems
  • The hype of Functional languages
  • Strongly typed vs dynamic languages
  • Platform independence vs platform dependence (of languages and technologies)
  • Software development as an engineering discipline or an art, and everything in between
  • Serverless, as the solution to all problems

There’s plenty of other ideas and concepts that could be part of this list, and I’m not highlighting anything in my list to say these ideas good or bad, but when you look back it’s interesting how ideas come and go over time. People come and go too, some noticeably bringing new ideas and passion with them, sometimes rediscovering ideas again from the past. Sometimes as champions leave the industry their ideas no longer have a voice and their ideas disappear with them too.

If our industry is still in its infancy, is this cyclical, repetitive behavior just the industry trying out new ideas to see what sticks? Or is it that the people actively involved in championing ideas come and go too, bringing ideas in and sometimes taking ideas with them when they move on? Does this mean that as an industry as experienced developers leave the industry and new generations of developers come in, are we doomed to continually repeat our mistakes of the past?

Why code is hard to test

Junior Developer: I can’t write a test for this code, it’s too hard to test

Senior Developer: Who wrote the code?

JD: I did

SD: You’re saying the code you wrote is hard to test. If you wrote the code, who made the code hard to test?

JD: I guess I did

SD: Right, so can you restructure the code to make it easier to test?

JD: Yes, looking at it again, I could break it down into smaller methods that would be easier to test individually

SD: Great! In future, how can we write the code so make it easier to test?

JD: Well if I think about how I’m going to test the code as I write it, then I can definitely write it in a way that would make it easier to test

SD: Great! And if you write your tests before you write your code, that would help even further with that approach, right?

JD: Yes, I guess it would.

TDD is not rocket science.

Good code feels good, bad code feels bad : Trust your instincts

There’s been many attempts over the years to measure code quality with quantifiable metrics, such as cyclometric complexity (a measure of complexity caused by nested conditional branches). An experienced developer who has seen good code and bad code will have an instinctive feeling whether code is good or bad. Gut feel is valuable because it’s almost always right. If you look at code and it feels wrong, you’re probably right. Based on experience, you get a feeling that something’s not right. The difficult part is nailing down what’s not right, and then refactoring to make it better.

There’s been a number of best practice principals established over the past decades of software development that have stood the test of time, and are widely accepted. There are many other ideas and concepts that are topics for hot debate, but these few core ideas seem to be largely accepted by most developers.

In order to understand what it is we’re aiming for, I’ll take a stab at defining what I consider to be the core qualities of good quality code. Quality code is:

  • easy to read, and easy to understand
  • easily testable (with unit tests)
  • easy to fix, and easy to modify

You could expand this list with many other factors, but I think these distill the essence of high quality code. There’s a direct relationship between these qualities and the complexity of the code too. Remember cyclometric complexity measures the complexity of code based on number of branches – code that has a high number of nested branches with a high cyclometric complexity count would probably fail all the above qualities: deeply nested conditional code is usually difficult to read and understand, hard to test, and also usually hard to fix and modify.

As a broad generalized statement, simple code is usually high quality code, complex code is usually poor quality (based on the factors above).

The problem is, it’s not easy to write simple code, it takes time, effort and experience. It’s pretty easy to write complex code, but simple code usually takes considerably more time and effort. Without thought and attention, even as you work on simple code over time, there’s a danger that the code becomes more complicated the more changes are made to it. It takes effort to keep code simple, to keep it from deteriorating over time.

Best Practices for Writing Quality Code

There’s a number of established best practices in software development, many of which if followed help you towards writing code that achieves the 3 points above (easy to read, easy to test, easy to fix). Bob Martin in his book Agile Software Development, Principles, Patterns, and Practices, captures a number of these in the SOLID mnemonic:

  • Single Responsibility Principal
  • Open Closed Principal
  • Liskov Substitution Principal
  • Interface Segregation Principal
  • Dependency Inversion Principal

Other popular industry best practices include DRY (Don’t Repeat Yourself), and the YAGNI (You Ain’t Gonna Need It) idea also contribute and guide you towards developing simple, quality code.

Many of these concepts are deeply rooted in the first of the SOLID principals, the Single Responsibility Principal. If you have a Class that ‘does one thing and does it well’ (another common way this principal is expressed), or a method that does one thing, this code is typically easy to read, easy to test and easy to fix.

Many other best practices and guidelines tend to result indirectly in achieving the same desirable results. In many cases regardless of the approach or best practice followed, the ultimate result is code that does one thing and does it well. Code with this ultimate quality meets the criteria of easy to read, easy to test and easy to fix.

Why every developer should write a blog

It’s unavoidable at some point, if not on a regular basis, that as a developer you will need to produce some type of content in written form to share with your team or others. Since clear and concise technical writing takes practice, it makes sense that you should make a proactive effort to practice your writing. Writing a blog is a perfect (and easy, low or no cost) opportunity to get some practice.

There’s plenty more reasons however why blogging is beneficial and useful for all developers. In no particular order, here’s a list of reasons why you should be blogging:

Note Taking

Technology in software development changes and evolves fast. Chances are you came across at least one thing new over the past couple of days, and if it’s not going to be something you’re going to use on a regular basis, it helps to keep notes that you can refer back to at some point in the future. I can remember that I came across something similar a few months back even if I can’t remember the exact details, so creating a short one pager with some notes to refer back to later is incredibly useful.

Sometimes I also keep notes on the approach I took to solve a problem if it was something that took several steps. If I come across the same problem again several months from now, I’d rather refer back to my notes than working it out from scratch again. If the problem or the steps to solve it were interesting or I think may be interesting to others, I usually capture these steps as a blog post and share on my blog.

Collecting Snippets of useful code

Depending on what the information is, I vary how I capture the information. If it’s something that would be useful to capture as step by step in instructions with additional explanations and details, I usually capture these as a blog entry. If it’s something I don’t want to publicaly share, I sometimes create private posts that are not shared, or keep them separate in a notebook in Evernote.

If it’s a snippet of useful code, for simple, short lines of code I collect snippets using Github’s Gist (here’s a link to my public Gists as example of what I keep there), or for longer worked examples I create a project on GitHub and commit a code example there (the majority of my projects on GitHub are code examples where I was looking at something new and put together a worked example as part of learning whatever that new thing was – you can can take a look at the type of thing I keep on GitHub here).

Sharing Lessons Learnt with Others

The majority of time when I search for info on how to use a new library or framework, the most useful content that I find is usually an article written by a developer who worked through the steps on how to use something.

That content would not be there online unless that other developer took time to create the content and share. The great thing about the internet for software development is that content is easy to find if you Google, but that content would not be there unless those people took the time to write and share in the first place. If you have something to share, even if you think it’s obscure or might not be useful, there’s always someone else who is working on something similar, and they might be struggling to work something out – help out your fellow developers and share your knowledge.

Every developer has something they’ve worked on that would be useful to another developer trying to learn and get up to speed on that same thing. Even if you’re a new developer with a few months experience, you still have lessons you’ve learnt from your own experiences that would be useful to another developer with less (or even more) experience following their own skills development path.