Catch 22: Building Great Software

Building great software is hard. It starts with the choices you make and making great choices is really hard. After all, given the choice, we’d all choose to make great software right? So what’s the catch?

Picture a young guy out to buy a car. He really wants a convertible, it really fits with what he wants out of life right now. So he buys a convertible. He meets a girl, settles down, and before you know it, a baby is on the way. Now the convertible isn’t so great. What helped him when he was dating isn’t much help to him now. Now he wants a saloon!

Our current choices often conflict with future circumstances, however, if we focus too heavily on the future, we may actually make decisions which conflict with the present. A decision which is great for the future might be terrible news right now and vice versa. So how do we deal with this conflict? As it turns out, we tend to deal with it rather badly.

Decisions go stale. As business needs change, what’s relevant today is no longer useful in the future. In software development this means each feature will at some point fail to be relevant. Developers can see this as a failure to make the right choice rather than accept that ultimately our decisions will at some point be irrelevant. It’s likely that given such failure there will be the belief that enough learning took place to make a better decision in the future. We completely ignore the fact that at some point those choices will also become stale. Rather than turn our attention to being good at handling change, we repeat the cycle of trying to improve our decision making process on the basis that we’ve learnt enough that it won’t happen again. We naively think that next time our decisions will stand the test of time!

In extreme cases decisions can go stale before we’ve even acted on them. Businesses don’t wait for you to finish, they continue to change and learn. Being mechanically minded, let’s say we decide to build a saloon. This will take some time. While we’re doing this our child could grow up, leave home and we’re left wishing we’d built a convertible.

The conflict between present and future choices creates a problem in defining a successful software project. Success or failure at this level is outside our control: we can’t predict the future so we don’t know how relevant our choices are going to be over time.

In order to handle this conflict, we have to make it a non-issue. We have to be successful at adapting to change. What really matters to our success or failure is our ability or inability to respond quickly to change. When we can’t adapt quickly to changes, such as new or revised requirements, we have ultimately failed to manage the conflict. The good news is, if we understand that we have failed to respond quickly, we can invest time in understanding why that is and learn from this failure in order to improve our software development process to better handle change.

For a software team to be successful at adapting to change, you need to understand that you’re biggest asset or liability is your code. No decision you make can ensure your code outlives its usefulness, all you can do is ensure you can change it quickly, easily and without risk. To do this you will need clean, loosely coupled, well structured, unit tested code.

Similarly, business stakeholders need to help break the mind-set that features are perpetual. Software is evolutionary and features carry an amount of speculation about current and future value. Rather than telling developers what the business needs (or developers interpreting needs as perpetual), a “let’s try this next” approach to implementing features helps to reinforce the understanding that change comes with the territory.

Focus on handling change well. Your process should be about improving the ability to handle change by understanding and identifying your failure to respond quickly to change. Loose the ego and stop being frightened to admit failure and maximise the opportunity to learn as much as you can for the next change – it’s definitely coming!

The 7 types of customer value

How can a team of people, who’s only real tangible output is working software, create value for their customers?

Let’s start by giving our question some context. Our team of people, already have working software and customers. Within the team we have all the skills required to write, test and deploy code. The team handle the entire lifecycle of the working software, from birth to death. They talk directly to the customers. However for the sake of this post I’d like to treat the internal workings of the team as a black box. I’ll let your assumptions about what a software development team look likes fill that gap.

Our starting point is to consider seven basic types of customer value. The list is ordered in such a way that items on the right give you more leverage for value creation. However it is assumed a healthy team will balance delivery across all types, and know when to approach each type of work.

1. Information

This work involves no coding activities; the team provides the customer with information about how the software works. This type of work is about increasing the value-in-use of the currently working software.

2. Incident

Very few examples of working software these days does not involve some connection to servers. When there is a problem with these servers then things need dealing with quickly. The value to the customer is measured in the speed of the response.

3. Increment

An increment to the working software, often called a new feature or function, creates value by allowing the customers to do new things with the existing software. Since this new feature is based on speculation about what will work, the value may not be delivered, it is therefore considered less valuable than improvement type work. Removal of functionality would also fit in this category.

4. Improvement

Based on direct customer feedback, the team make small, evolutionary changes to the working software. Again this work increases the value-in-use of the current working software, but critically it is based on the experience of the customer using the working software.

5. Investigation

This experimental work requires a scientific approach and an appetite for failure. The value for the customer is the knowledge gained.

6. Impact

Rather than focus on the software, this type of work is based around a customer goal. It will often be related to a business deadline. A Minimum Viable Product would fit neatly in this category. Any measures of success would be based on business metrics.

7. Innovation

The team is able to take an idea related to the customers’ business and create new needs and wants. This is similar type of activity to a Lean Start-up Pivot. This is about doing something different rather than better.

There are two ways of super charging the customer value you create with each type of work. The first is for the team to stop order taking, and go find the problems for the customer. This pro-active approach works with all types listed above, a team that goes and hunts out these value creating opportunities will always beat a team who waits for the orders to roll in. The second way of increasing the value creating potential of the work is for the team to shift its focus away from software only, and move into working with the entire business system. This approach calls for the team to embrace the customer as a member of the team, so they can work together on making changes to the wider organisation or system in which the customer operates.


Context Switching

The dreaded context switch. I hear about it all the time. I have to drop what I’m doing several times a day to listen to people discuss it (chuckle). Jokes aside, I’m genuinely interested in the reasons why people want to avoid switching context.

Up until very recently I was convinced context switching was a bad idea. I would also have assumed any books that deal with context switching would justify my belief Q.E.D. style, case closed. I’ve been wondering lately if my thinking is broken and that I’ve been fighting for the wrong cause.

So what is context switching? In my world we are talking about changing from one deep train of thought to another. As a developer it takes me a while to get my head round the code I’m looking at. If I have to break my concentration, clear my registers and push what I was thinking about onto my mental stack for later, it takes times. A familiar example would be working on the code for a project and an urgent problem comes in that requires my attention to be diverted to the codebase for another project. Everything I was holding in my head about the code I’m currently working on gets lost forever as I bring my thoughts to bear on a different problem.

Now I’m sure you might be thinking there are also sorts of time management practices you could apply to handle this. However, I would urge you to think twice about how you tackle context switching. Is it really a good idea to rush into this problem with your productivity hat on and try to optimize the process to avoid context switching? If you do, much simpler and more important questions may go unanswered: are people finding context switching hard? If they are: why is that?

Recently I read two very different books. Although they turned out not to be so different after I’d read them. One was on psychology, the other development.

The book on psychology “Think Fast, Think Slow” discusses how we handle the process of decision making and problem solving. It will come as no surprise that we need to engage a large percentage of our brain to solve problems. The harder the problem the more time and thought you will need to understand the problem and resolve it. My take away is that there are types of work that we struggle with. We’ve all put a book down because it was just too damn complicated. We’ve all read a book where each page was jammed so full of information it took ages to read. I’ve also read similar sized books in a few hours. Those books I’ve read quickly were just… well, less complicated!

The book on software development was called “Clean Coder”. It challenged some of my long held beliefs about good software development. It especially challenged how I think about being in the zone. I love being in the zone. I love being so engrossed in difficult problems that hours seem like minutes. I love holding hundreds of lines of code in my head trying to figure out where it’s going wrong. I’ve woken in the morning knowing how to fix a bug in some thousands lines of assembler I’ve memorized. It’s addictive and gratifying. There can be a certain amount of bravados about being better at handle complicated problems than others. Is boasting about fixing really hard code like totally unreadable assembler a good thing? Is being so engrossed in a problem that you lose sight of the big picture the best approach?

Both these books were telling me something about complicated work. It can be difficult to get your head round. We don’t want to be disturbed when we’re engrossed in complicated work because it’s difficult to get engrossed. If you like a challenge, it can be a lot of fun. We don’t want to be disturbed when we’re engrossed in complicated work because we’re enjoying ourselves. Whether context switching is time consuming or a killjoy, the fact is: difficult challenging work is time consuming.

If context switching is a problem, you need to understand if the work is the underlying cause.

Maybe you’re thinking: “Duh? Of course software development is hard. We need to focus more and have less distractions to deal with it!”

Maybe you’re thinking: “I kind of get it, but we can’t make the work less complicated, we have no control over the work coming in!”

Maybe you’re thinking: “How can I make the code I have to read all day simpler and clearer?” If you’re thinking about the possibility of making things simpler, you understand.