The ABC of Continuous Delivery

You probably know the triple L of real estate: location, location and location.

In the same way some would argue that the three most important focus areas, the triple A of continuous delivery, are automation, automation and automation. While I believe there is some truth to that, I am even more convinced that it’s not AAA, but rather ABC.

The A is obviously automation. Read the book, and you will see why it is so obvious.

The B is obviously baby steps. Read my last blog post, and you will see why it is so obvious. I will blog more about that later.

The C is not-so-obviously clean code. You didn’t see that one coming, did you? It could also mean consistency, which might seem to be a sub-set of clean code, but if you ask me it is much more than that and also much more important. I will blog more about that later.

Why is Clean Code so Important?

When I write about clean code in this context it is mainly in the Uncle Bob sense. Read the Clean Code book, and you will know what I mean.

You may wonder why it is so important to focus on the nitty-gritty details of code structure. Isn’t the larger picture of patterns and practices more important?

The answer to that is, yes, patterns and practices are absolutely infinitely more important. But keeping the code clean is important for the simple reason that you cannot write code unless you read existing code, so in order to efficiently write code, the code already written must be readable. And code that is structured strictly according to agreed upon rules is more readable than less consistent code.

While I am a fan of Uncle Bob, I am also sceptic about coding standards that cannot be automated. So, I must admit that the code guidelines I follow for my C# code is largely determined by close to 100% default ReSharper settings + a handful of StyleCop rules. These rules are sensible, they are automated and thus really easy to follow. They do not automate all aspects of clean code, but they go far in that direction. I also use a plugin to ReSharper for spell checking, as it helps me to semi-automatically use meaningful identifiers.

For a team that consistently follows such agreed upon and automated rules the benefit is obvious, since a developer will feel at home in any parts of the code, regardless who wrote it (well, honestly it takes a bit more effort to fully achieve that, but I will blog about that later). This is important for a team that needs to continuously deliver.

How does this Relate to Lean Manufacturing?

Some will argue that Lean Software Development and Lean Manufacturing differ in at least one important aspect.

For Lean Manufacturing, it is important that any kind of variation is minimized, since variation tends to create a ripple effect that will cause trouble in a physical factory. This effect is described in an easy to understand fashion in the two novels I mentioned in my last blog post.

But software is different, right? Minimizing variation would kill creativity and all software projects are so different and novel that it would be futile to fight variation, right?

If you ask me, we must fight unneeded variation in code. If you insist on placing curly brackets in your own way, and in general follow you own style instead of a style agreed upon by the team, then you create unneeded variation which will cause you team mates to be less efficient.

Instead, spend your brain cycles on whatever makes you product valuable. If you don’t know what that might be, find yourself another job.

Notice how fighting unneeded variation goes hand-in-hand with automation. Another example of this is the use of an automation tool that you already use every day – the compiler – to write code without compiler warnings. Compiler warnings can actually make a lot of sense and if you ignore some, you might accidentally one day ignore one of the really sensible compiler warnings.

On my team, we have set the warning level to the highest possible, and defined that warnings should be treated as errors.

How to get There

If you write new code in a new project, it is a no-brainer to write clean code from day one.

If you work on legacy code, as most of us do most of the time, you need to think a bit about how to get there. Do you change all the code in one revolutionary check-in? Do you evolve the code by only following the guidelines for new code? Do you clean existing code only if you need to make significant changes to it?

If you ask me, you might as well clean up as much code that you can automatically, if you have a tool that you trust. Once you need to do manual changes, you might break otherwise working code. Then you need to think a bit more about the process and be cautious – especially if you don’t have a safety net of automated tests.

That’s It

All this is really a no-brainer. Just do it, gain the benefit – and be prepared for the next level of clean code in which you consistently apply agreed upon patterns and practices.

On the other hand, if you find this level of clean code to be really hard to achieve for a team and its source code, you should consider if this team really is prepared to embark into the world of continuous delivery.

Continuous Delivery

How does the topic Continuous Delivery fit in a blog which is mainly on code architecture and code crafting?

In this post I hope to convince you that it fits quite well.

I am working on a team which has successfully practiced continuous delivery for some time and it turned out that pretty much everything we did affected our ability to actually deliver continuously.

In this context everything literally means everything in the software development life-cycle, from stated business goals to provable value for the customers. This does not only involve crafting the code but also deriving scope from business goals in a way that can guide the further process, which includes various kinds of testing and verification in parallel with coding, as well as operations tasks. Continuously.

The bad part is that if you wish to practice continuous delivery you need to rethink everything you do and you need to break quite a few habits. The good part is that it does not involve radically new practices, you only need to take existing and well-known practices more seriously and apply them consistently. Continuously.

It is common knowledge that the way we structure code, the way we break down complexity into manageable bits and the way we apply well-understood and agreed upon patterns consistently greatly affects our ability to deliver. So it is not a surprise that when we need to continuously deliver with a short cycle time, then all this becomes even more important.

What Is Continuous Delivery?

The short answer to that is look it up or read the book.

If you ask me, continuous delivery is really Lean Manufacturing principles applied to software development. The principles from physical manufacturing have been modified slightly in order to make sense in the software development world.

Do Lean Manufacturing Principles and Processes Really Fit With Software Development Ditto?

It is surprising how many physical manufacturing processes fit nicely with software development processes.

In lean manufacturing you want to have a short cycle time, meaning the time from feeding raw material into the factory and until the product is finished (and by then the product is hopefully valuable to the target user). This sounds awfully similar to what we want to achieve with continuous delivery, doesn’t it?

One way to achieve a short cycle time is to produce small batches, i.e. producing only a small number of items of a given type before switching to making another type of item. The challenge with small batches is that it takes significant time to set-up machines between two batches. And does it make sense to produce, say, 10 items in two hours, then spend 2 hours setting up a machine in order to produce 10 items of another type in two hours etc.? Wouldn’t it be better to produce 1000 items per batch, thus making the set-up time relatively small? The answer is that, yes it probably makes sense to have a small batch size, and no building up a large inventory is probably not a good idea. Optimize the process of setting up machines rather than increasing the batch size thereby avoiding the large amount of Work In Process (WIP) at any given time. The rationale is really quite simple and the logic makes a lot of sense. If you don’t believe me, I suggest you read the novel The Gold Mine: A Novel of Lean Turnaround. Yes, it’s a novel so it doesn’t really feel like working when you read it. But it will give you a gentle introduction to lean principles in manufacturing. (If you get really fired up on this topic I suggest you also read The Goal: A Process of Ongoing Improvement. It will teach you about the importance of focusing on bottle necks in the process.)

In the world of software development we have a similar challenge with batch sizes, the batch size in this context being the amount of code that we deliver (or anything else we deliver, but let’s focus on code for now).

We see the batch size challenge at multiple levels. At the highest level, the business would like us to turn the business goals into value for the customer as fast as possible, and one way to do that is to initially focus narrowly on minimal functionality. That’s a no-brainer, you say, but the business will never accept it – they always want it all and the want it yesterday, right? Well, it can be done. As Eric Ries describes in The Lean Startup: How Today’s Entrepreneurs Use Continuous Innovation to Create Radically Successful Businesses it makes a lot of sense to quickly make a Minimal Viable Product (MVP) that can be validated and used in the further process. That is a small batch size which is used to achieve a short cycle time in software development!

We also see the batch size challenge for individual check-ins into a version control system and when merging change sets among branches. If you are really continuous you do continuous deployment and each check-in will be deployed directly to the live production system. This is not as risky as you might think if you have automated as much as possible, including tests, and if you can live with occasional hick-ups which you need to address fast. In my team we do not deploy each check-in, although we do deploy often after a short manual verification process that augments all our automated processes.

My advice here is to always strive at delivering baby steps, meaning small focused check-ins and small focused features. Any process which is in the way of doing baby steps must be optimized. If gated check-in takes 6 hours on a good day, then find another way to check the code. If code reviews have response times of several hours or days you need to look into that part of the process. If testing is a bottle-neck you need to address that, probably by adding resources in the short-term and doing more automation in the long-term (so that manual testing can be focused on new and UI centric features). Our goal must be to have as little WIP as possible, which in this context means code that we have spent time on but which has not yet been fully verified and turned into value for actual users.

That’s It

It is really that simple, deliver baby steps quickly, optimize any process that prevents you from doing that, automating as much as possible on the way.

But even though it is simple to state, it is not always easy to do it. I am writing primarily to code craftsmen, but before we go deep into core coding topics, you should convince those who control your process to read on Lean Manufacturing and Lean Startup. And if they get really fired up, they should also read Specification by Example: How Successful Teams Deliver the Right Software. In fact you, the code craftsman, and your testers should also read it – it could potentially help all three disciplines to work better together.

For true continuous delivery to work, developers must accept to be part of the full process, so a developer must accept to also partly work with operations. Read The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win and accept that we are no longer mere developers – from now on we are DevOps.

This was a long introduction. In my next post I will go deeper into how to craft code in the world of continuous delivery. I hope that by now you agree that successful continuous delivery requires that we think differently about the entire software development process. After my next few posts I hope you agree that we also need to think about code structure differently.

Then again, maybe you already do. After all, the coding practices I am going to describe are all based on existing knowledge and generally accepted practices, so maybe you do it all already.