Fear, and When To Fear It
Fear is good, but letting it get in your way is just plain unnecessary. Here are some of the many tricks for pushing through.
Fear is a rational response to change. Fear is the enemy of change.
I could not find a source for this following graphic, but it quite nicely illustrates how fear is a barrier that keeps us contained within our comfort zones.
We developers share a nasty secret. We all know just how fragile the world of software is; how easy it is for a slight change to create some unintended consequence and take down an application.
So we're (quite rightly) frightened to make changes. We resist making them because we can't be sure that they will work. We put procedures in place—meetings, committees, sign-offs—so that when a change is made, the blame gets shared if something goes awry.
Don't get me wrong. Fear is a valuable feeling; it stops us from being reckless. But too much fear paralyzes us.
So here are some suggestions for exploiting the benefits of fear without having it getting in the way of change.
Good practices mitigate fear
This sounds obvious, but consistency is one of the most important ways to alleviate fear.
Have you ever worked on a project where the build instructions were a three-page document, and where deploying software involved copying a bunch of files into particular places on some servers? I have, I and can tell you that after installing a new release I was in a state of mild anxiety for the next day, waiting for the inevitable phone call from an irate customer or boss.
These days, all my deployments are automated: a single command will update any number of applications and services on any number of hosts. And now I deploy on pretty much every commit I make.
Automate to Reduce Fear
This can be taken further if you implement a Continuous Integration/Continuous Delivery pipeline. To do this, you'll
need to be using version control,
have a release strategy (perhaps using tags or branches),
have decent tests,
use automated deployment,
and have a way of rolling a bad deployment back.
This is something that you grow into as a team: you shouldn't just announce one day you're switching to CI/CD, But if you have that as a goal, it will inform the decisions you make while constructing the project.
Having automated testing and deployment takes a lot of the fear out of changing software. What's more, the fact that deployment no longer takes a lot of ceremony or time means that you can deploy smaller changes. You won't be as afraid of a 2-line change as you will of a 200-line change.
Good Practices Include Good Code
Every change you make builds on the existing codebase. And if that code is unreliable, hard to understand, or just plain wrong, then you're quite right to fear any changes you make.
So maintaining good code hygiene is an essential requisite of approaching code changes without fear.
Take Smaller Steps
When you're unsure of the ground ahead, taking small steps is just good sense.
You might not be unfamiliar with the domain, uncertain of the customer's needs, or uncomfortable with the design.
Whatever the reason, the fear brought on by this uncertainty can lead to the infamous writer's block: the fear of the blank page.
Alleviate that fear by reducing the impact of getting it wrong. If every step you take is a small one, backtracking is easy.
Small Steps Are Safer
Sometimes you can drive this process with tests. Pure Test-Driven Design (TDD) asserts that you never write code without a failing test. AT the extreme, that means you can't start coding a new module without first having a test fail trying to reference the (nonexistent) module.
At a more pragmatic level, you can do something similar: write a test of something trivial, and then write the very simplest piece of code to make that test pass.
My advice is to be very cautious with this approach. It is very easy to start following a drunkard's walk (a process where each step is some random distance and/or direction from the end of the previous step) where successive tests add to the codebase but take you no closer to the goal.
Walk With Me
Sometimes you can involve your customer in the small-steps path.
They are asking for a bunch of functionality; do they need it all at once? Or is there some small subset that could be delivered early and that would still give them some business value?
:Step With Your Customer
The benefits to your customer include:
they get to see their software as it is being developed, given them the opportunity to learn and to make adjustments;
they get a better feeling for progress and likely timescales;
they start seeing a return on their investment early;
they'll start to see other opportunities for development.
You also get many benefits:
You can approach the project in smaller, less scary, chunks. This goes a long way to reducing the fear of starting.
You get to shake down your build and deployment practices.
You get feedback, and any changes are easier to make because they're localized to a smaller delivery;
* You get the confidence to make future changes.
Most importantly, though, doing this builds a relationship between you andyour customer; they'll know that, even if you deliver stuff that's not quite right, you'll make it better. You'll know that your customer will change their minds, but will work with you to find ways to make the corresponding software changes easier.
In this environment, handling change turns from being a confrontation to a more enjoyable "you bet!"
Cheap Code Is Easier to Throw Away
When I'm writing something in a new domain or using new tools or technologies, I worry that I'll spend a month creating something only to discover that, finally, I understand, and that what I've just done is basically junk.
I fear that because I've done it—many times.
Nowadays I overcome that fear by prototyping; writing code to try out ideas that I know I'll be throwing away. This code will be ugly. It won't have any error handling (unless I need to handle errors to explore the system).
It might not be in a repository, and will only have tests if tests are the cheapest way to learn what I want to learn.
Prototype To Resolve Fear
I recently used GraphQL in a project. Having never used it before, I started with a piece of code that sent a simple query off to an API. To get that working, I had to work out which GraphQL library to use, how authentication worked, how to express queries and create fragments, and what error responses looked like.
The resulting code would have made Dr Frankenstein proud: snippets of code cobbled together from a bunch of web sources, GitHub archaeology, and random experimentation. Half-way through the second day, something flipped in my brain and I felt like I got it. So I created the repo for the actual project and started coding. Maybe an hour later I had what I felt was well-structured and resilient code chatting away with the service API. I broke my own rule and kept the prototype code lying around in a temporary directory: it was a useful playground when I wanted to try out something new and didn't want to mess up the main project.
“We Have Nothing To Fear But Fear Itself”
Churchill’s aphorism still sounds good (until you stop to parse it). The problems we anticipate are not the enemy; they are simply the challenges. It’s the fear of those problems that we have to overcome. And hygiene, small steps, and experimenting are just a few of the many charms we can use to banish fear whence it came.