Take control of your code quality
We all know how valuable it is to keep the quality of your code high. Working on a high quality codebase is more enjoyable and enables us to deliver value much more effectively for our users and yet, time and again I hear engineers saying, “I am not allowed to spend sufficient time on code quality”.
In this talk I answer the following questions:
- What is the value of maintaining a high quality codebase?
- How do you get your colleagues and managers to support you in maintaining high quality in your code?
- What practices can help ensure you maintain a high quality code base?
đź“„ Transcript
I am Joel Chippindale, the CTO at Unmade where we use computers to program knitting machines and support on-demand garment manufacture.
I’m here today to talk about taking control of code quality. I’ve been managing software development teams for over 15 years and what I hear again and again in these teams is people in engineering positions saying, “I’m not allowed to spend sufficient time on code quality”.
There are a whole range of reasons why people say this.
Some of those reasons are external. Perhaps they’re feeling under pressure of deadlines, perhaps from the product manager they’re working with or the CEO of the company or their CTO. Perhaps it’s about reward and thanks in the company you’re working in. We tend to get thanks when we solve problems that people can see, rather than when we do the invisible work of improving code quality. That inevitably guides some of our behaviours.
Some of the reasons are internal. We are often motivated by making software work and we enjoy getting software working and solving problems. But tidying up after ourselves is sometimes less enjoyable, less rewarding. Sometimes we say this because we’re not sure how to improve code quality. I have to hold my hand up and say that I have done this in the past. I’ve said I’m not allowed to spend sufficient time on code quality when what I really meant was I don’t know how to improve code quality.
I have a question for you.
Do you feel like you’re spending sufficient time improving the quality of your code?
Or, do you feel that you’re spending too little time improving the quality of your code?
I gave this talk recently to an audience about 80 people and about a fifth of them said they felt they were spending sufficient time and about a half said that they were spending too little time.
In this talk, what I want to do is address what we mean by high quality code. What is it? Why is it valuable?
I also want to talk about some of the ways we can talk about spending time on improving quality of our code and improve communication both with other team and within our teams.
And then lastly, to talk about some of the practices that help you develop high quality code.
Starting with the first question.
We talk a lot about code quality. We clearly care about it, but what do we mean? Why is it important?
To help illustrate this, I’ve made up a graph. On the Y axis, we’ve got the pace of delivery of valuable functionality for your users. On the X axis, we have time.
This is a fairly typical graph of the pace of delivery over time.
When we start off on a project we find ourselves able to deliver lots of value very quickly. As time passes, making valuable changes gets harder and harder.
When we are on the right hand side of this graph, we are likely to be complaining about spaghetti code, about flaky tests, about inappropriate abstractions. The code makes us feel foolish. Changes that should be easy and seem really hard.
I have added a blue line on this graph to represent a high quality code base and how that develops over time.
You can see in this graph that it starts off a slightly slower pace of delivery. The team working on this code base are probably spending a bit more time thinking about the design of their software, perhaps doing more refactoring and so it’s a little bit slower to begin, but they’re able to maintain a constant pace of delivery over a long period of time.
If we’re able to do this, it will help us achieve more overall. You can see the area below the graphs is much bigger for the blue line. It helps us feel smarter. Changes to the code base that should be easy to tend to actually be relatively easy to make.
Although I haven’t put a scales on these graphs, in my experience crossover point between the paces of delivery for high and low quality software happens earlier than people expect. It’s often hours or days or weeks into the project rather than months or years. If your code base is going to last a long time, then it’s really important to be focusing on code quality.
Of course for spike, for example, it matters much less. If code is only going to last for a day or two the quality is far less important.
High quality code is code that is easy to keep changing.
This is the only definition of high quality code that is useful. It doesn’t matter whether you’ve got a hundred percent test coverage. It doesn’t matter whether you’re writing functional code or object orientated code, it doesn’t matter if you followed SOLID principles. What matters is that your code is easy to keep changing.
Code that is easy to keep changing is code that is enjoyable to work on. It helps you feel smarter and enables you to do more valuable work for the organizations you work for. Everyone wins and that’s why it’s the right lens to look at code quality through.
It’s not just me who says this.
In 2001, the Agile Manifesto was released and it’s been enormously influential on all of our working practices. 12 Agile Principles were included with it’s release, and this is Principle #8.
Agile processes promote sustainable development. The sponsors, developers and users should be able to maintain a constant pace indefinitely.
That’s exactly what we’re talking about with high quality code. Maintaining a constant pace indefinitely.
This is not easy to achieve and you have to be very disciplined.
These graphs may make it look like there’s a single decision at the beginning of a project as to whether we’re going to invest a bit more time in develop, high quality code, or we’re just going to go as fast as we can right now. However the reality is there are many decisions that you make every single day about this.
Your real project, won’t be quite a smooth graph like this. This means you have choices now and even, if you’ve dropped away from high quality code, you have the opportunity to build back towards it.
We need to build trust to maintain code quality because we need to be supported by the people around us, even those people are not engineers.
The people who work with you want you to do well.
They want to get the best from your work, but work on code quality is scary for them because much of the work is invisible. They can’t see the outputs and we don’t have good measures for sharing how well we’re doing. We need to build trust with those around us that the time we spend focused on code quality is valuable.
I want to tell you a story from when I joined Unmade to help illustrate this. They had developed some really innovative technology to generate programs dynamically for knitting machines that made it possible to knit out unique patterns at scale.
You can see in this video, how we worked with New Balance to launch the world’s first trainer with a custom knitted upper, the NB 111.
The code when it was first written was high quality. But as we became more successful the volume of garments going through the systems became much higher. This meant that our code was failing for particular edge cases on a much more regular basis. It had become a daily task for engineers to go through those failures and fix up the errors by diving into the database or manually re-entering jobs into our queuing system.
The engineers in the team had got used to this. When I asked them why they weren’t spending time to improve the systems they said, “We wouldn’t be allowed to to spend the time to do this”. So I asked them to take note for a couple of weeks of roughly how much of their time was being spent dealing with these failures.
Over the next two weeks, they worked out that this was taking about two to three days each week of the time of one of our engineers. I also asked them how long it might take to fix this. We weren’t sure, but were reasonably confident that if an engineer spent a month working on this we could resolve most of the sources of failures.
When we took this information to our Chief Product Officer, it was a no-brainer for him. He was clear that we should prioritise work on this. He could see that we were growing as a company and growing the volumes that we were processing and that within a short period of time, this was going to be a full time job for one of our most experienced engineers, just to keep the system running and that investing a small amount of time now in reducing that overhead was clearly really valuable.
There are a few approaches, that this story illustrates, for how we can talk about code quality.
The first is to speak in terms that makes sense to others. People outside your engineering team don’t care about technical debt.
…people outside the engineering team hear this, “blah, blah, blah…”.
And they know, because they’re experienced, that what we mean the work is going to be slow and delayed.
What we need to do instead is to talk in terms of they make sense to them. Our time is expensive and high quality code is about making it possible for us to deliver much more value in the coming months. If we focus on this, then we can explain why we should focus on code quality.
In the story I told, we talked about the costs in terms of time spent by engineers and we put a number to that. It wasn’t a precise number, we said about 2-3 days a week, depending on the week. We also put a cost to fixing the issue and although, we didn’t know the exact amount of time it would take, we had a rough idea.
Secondly, it’s really important to show that you value the same things that members of other teams value.
Hopefully you feel like you are working as one team with some of the people outside the engineering team. In a company like Unmade, where there are only 30 people, we all feel like were working towards the same aim. But if you’re in a larger company, there’s probably a smaller unit of the company you’re working with where you feel like you have a shared goal.
I’ve worked with engineers who are openly dismissive of other disciplines, maybe sales or marketing or design. If you dismiss the work of others, they’re unlikely to trust that you are making good judgements about how to use your time. Show that you listen. Tell them that what they do matters to you, because it almost certainly does, even if it isn’t what is most exciting to you.
Again, that was what we did in the story earlier.
We didn’t talk about doing this in order to make engineers happier, although clearly it would. Rather we talked about it in terms of the value that it would provide to the company and how it would help the Chief Product Officer achieve their goals.
And again, it is not just me who says this. Agile Principles #1 says,
Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
My last recommendation is, “don’t bullshit”.
Don’t be tempted to exaggerate, perhaps because you believe it is the only way to get the result you want or because you believe others will bullshit.
In the story I told we could have exaggerated the costs and said that it was already taking two people all of their time to deal with the failures, in order to make it more certain that we’d get the answer we wanted from the Chief Product Officer.
However this would break trust in the long run.
Shape the solution.
This is from Intercom’s engineering principles and they say
We never blindly execute on requirements, defined by others. We deeply understand the value of our work and help design solutions, which efficiently delivers that.
The key idea here is our skill is not just building software, but understanding how to translate complex real world problems into ways to solve the problem that we can deliver efficiently. Unless we understand the complex real world problems that we’re trying to solve, we’re not going to come to the best and simplest solution.
The scout rule.
I can’t emphasize this enough. This comes from the idea that Scouts should leave the camp-ground cleaner than when they arrived. That’s how we should be thinking about our code base as engineers, every commit, every user story we implement should make the code base better than it was before.
There are a lot of judgement calls to be made here. If you’re adding functionality then you’re probably making the system more complicated. How do you make trade-offs around this? There are lots of interesting conversations to be had within your engineering teams about this subject.
This rule implies also implies that you should be refactoring all the time.
Refactoring first to make it easy to make the change you need to make. This has the advantage of needing less discipline than tidying up afterwards. But also refactoring during your work on a feature and after you have got it working too.
This should be true for every commit and every feature you implement.
Only give the option to take a different approach in exceptional circumstances. Don’t just default to dropping code quality as soon as there’s a bit of pressure.
I think it is helpful to think of refactoring in terms of what happens in a professional kitchen.
Chefs work under an enormous amount of time pressure. They’re working really fast, but if you watch them, they are cleaning all the time. They clean their station before they start preparing a dish, they clean their station during the time that preparing a dish and they clean the station afterwards. They’re always trying to make their workspace better.
Again the Agile Principles speak to this and #9 says,
Continuous attention to technical excellence and good design enhances agility.
This is exactly what the scout rule is helping with.
Lastly, the small improvements you are making every time you make a change, won’t be enough on their own. Every so often you need to make a much bigger change to improve the code.
It’s really important to make a quantified case. That’s what we did in the story I told about Unmade. Think about why it’s good for you and your company to make the investment in this bigger change and about the impact it will have.
Express the impact in terms that they will understand. You don’t have to be certain about the impact and the costs, but you are in the best position to judge them. You should stick your neck out and tell people what you think.
You don’t need to be in a lead role to do this. If you make a quantified case for a larger improvement, then you’re making it easy for people to make more informed decisions and it will be easier to persuade other people in your team.
High quality code enables us to keep making changes at a sustainable pace. It makes us feel smarter. It makes our jobs more enjoyable and helps us more achieve more for our organisations.
Build trust with your team by listening to others and communicating clearly in a shared language.
Last, but not, least here are three practices that will help you
- Shape the solution
- Follow the scout rule
- Make a quantified case for larger improvements.
Thank you very much for listening.
I really enjoy talking about this subject, so don’t hesitate to ask me questions if you have any, thanks for your time again.
đź“Š Slides
Other versions of this talk
- Nov 2022 - CTO Craft Con
- Feb 2020 - London Python Meetup - Slides
Further watching, reading and listening
- We invested 10% to pay back tech debt; Here's what happened
Alex Ewerlöf on the value of setting aside reqular time to improve code quality - Reduce friction
Minimising friction is key when it comes to helping your team succeed, and Ceej Silverio's guidance really hits the nail on the head - Ways your teams can (realistically) prioritize code quality
A LeadDev panel discussion about prioritising code quality with Eleanor Saitta, Usha Kuchibhotia, Sanket Saurev, Maude Lemaire and I - A rubric for evaluating team members’ contributions to a maintainable code base
Chelsea Troy gives some excellent advice on the skills that you and your team need to develop in order to keep a code base maintainable - Sandi Metz: Making is easy, mending is a challenge
Robby Russell interviews Sandi Metz as part of his podcast "Maintainable" and she shares her wisdom and advice on how to keep code maintainable. - Technical Debt - a guide for developers and product managers
Alex Warren's guide is full of good advice for keeping on top of 'technical debt'. - How To Explain Technical Debt To Executives. Hint: It’s Not Technical.
Sam McAfee encourages us to focus on the organisational side of "technical debt" - Running an agile principles study group
How to run an study group to improve the understanding of and adoption of agile principles - Foundations to build on: Intercom’s principles for building product
Des Traynor outlines some key principles for effectively developing a product and the engineering specific principles are the source of "Shape the solution" in this talk - Why not fix your technical debt?
Alex Warren's insightful talk encouraging you to take control of improving your code quality - Is high quality software worth the cost?
Martin Fowler highlights that developers often justify attention to quality by justifying through the need for proper professionalism. But this moralistic argument implies that this quality comes at a cost – dooming their argument. - Simple made easy
Rich Hickey on the value of simplicity in our work on software and the siren call of easy. - Principles behind the Agile Manifesto
These 12 principles form the basis of the Agile Manifesto and I regularly refer back to these when making decisions
Reactions
Really enjoyed the talks at #londonpython last night. Will definitely be using some of the ways of talking about software quality outlined by @joelchippindale.
✏️ Edited in Oct 2020 to add a transcription, slides and an embedded a video.
This is part of a series of talks and articles about the work and practices of my teams and I at Unmade.