"I don't like complicated code." Michael Feathers on Legacy Code and Technical Debt

An interview with Michael Feathers and Matteo Baglini

Who’s the person that comes to your mind when thinking about Refactoring Legacy Code? You can’t miss him: it must be the one and only Michael Feathers!
But there’s much more than Refactoring and Technical Debt, and this conversation with our trainer Matteo Baglini aims at uncovering some of the other aspects of Michael’s work and life. Enjoy!

Matteo: Hi Michael, thanks for being here!

Michael: Thank you! I look forward to visiting Milan.

Matteo: It was 2004 when you wrote Working Effectively Legacy Code. This bestseller is now considered a milestone in software development and the go-to book when it comes to legacy code and refactoring. Have you ever thought about writing a second edition, or have you ever had the motivation/drive to publish a follow up book?

Michael: That’s an interesting question. I’ll likely write a follow up to the legacy code book at some point, but I’ve been spending a lot of time looking into error handling and the issue of excessive checking in code. I’ve been writing a book about this. The working title is ‘Unconditional Code.’ My plan is for it to be out next year.

Matteo: What kind of impact has the book had on your career and, ultimately, on your life?

Michael: It has had more impact than I ever expected. What I knew in the beginning was that it was a subject no one wanted to touch. At the time I wrote the book, the industry seemed to be pretending that software design was something you did on new systems, that design is a ‘blank-slate.’ I suppose it’s convenient to assume that, but the reality has always been very different. People just didn’t seem to want to explore the gulf between the real and the ideal.

As I wrote the book, I could see how it would be a useful contribution. I thought that I would put it out into the world and then explore other topics, but after its release I became the person to contact when you want to move past chaos in a code base.
As a result, I’ve visited many organizations and, perhaps, seen more difficult code than anyone alive. I’m happy, however, that I’ve been able to help many teams move forward toward better practice.

Two of them are mentioned in this blogpost… can you guess their names? (Skills Matter’s muCon 2017, London)

Matteo: How have your views on legacy code changed over the past years? What kind of differences can you see in today’s code bases as opposed to those one could see 10-15 years ago?

Michael: There are some fundamentals that are the same… Long methods, mixed responsibilities and deeply nested conditional logic, but today I see more entanglement with 3rd party services and frameworks.
In a way, that is a measure of success. We can do more while writing less code. But, it also places more constraint on our designs. The testing situation, in particular, can be much harder.

Matteo: You’re currently working as a consultant for R7K Research & Conveyance. What’s the main focus of this company? What are you currently working on?

Michael: R7K is my “one person” company.
Generally, I spend my time consulting and training. The name comes from the thought that a lot of what I do is research, and I convey it to people I end up working with.

Matteo: One can read the following statement on R7K’s homepage: “company specializing in software and organization design”. In which ways do the company organisation impact software development? How can the way a company is re-modelled/changed help us solve the software legacy issues?

Michael: What I seem to invariably find is that systems are systems. We can’t just look at the technical systems of an organization without looking at the organization itself.
Conway’s Law points to this: “organizations which design systems… are constrained to produce designs which are copies of the communication structures of these organizations.”
I think this is much deeper than most people realize. Technical Debt, for instance, is an impact of organization and process on code. Code impacts organizations too.

The first step is noticing the effects. Why, for instance, is a particular area of a system incurring the most change? Does that change belong somewhere else? Does the organization take the adaptability of the code into account when it is planning? There are an endless number of things you can do to tune a software development organization once you see the whole system.

Matteo: Have you noticed any progress in the way software is being developed? What’s the biggest progress you’ve seen so far?

Michael: Agile was a large step forward, but I think it came at a cost. The conversation in that community became very process-focused despite the best intentions of all of the people involved early.
As an industry we went from spending too much time talking about code, design and architecture to practically none. Most of that conversation moved to the DDD community and a few others.

That said, we have made progress. It’s great to see more people moving towards functional programming. Microservices, as well, align very well with Conway’s Law at a meta level.
I think the next step is merging the conversations about people, process, and technical.

Matteo: Let’s talk about microservices: It’s possible that one’s legacy code is now made up by microservices. How do you deal with these “distributed big balls of mud”, as opposed to the well known “big ball of mud”?

Michael: Back in 2014, before we got this far, I was writing about this. In a blog post titled “Microservices Until Macro Complexity” I wrote “When we break up big things into small pieces we invariably push the complexity to their interaction”.  It turned out to be true. It’s the nature of cohesion and coupling. But, despite that, microservices have made quite few systems possible that weren’t possible before.
I’m still looking for people to address contemporary macro issues of service and collaboration design in a deeper manner. My experience is that cross-service refactoring is much harder.

Matteo: Alongside with working on legacy code and refactoring, you’ve been dealing with functional programming too. What kind of impact do functional programming paradigms have in terms of legacy code? How do breaking dependencies change when we’re dealing with functional programming?

Michael: I’d been doing functional programming for a while before I looked back and realized that most of the issues that I was presenting techniques for in the legacy code book were issues of mutable state.
If you have a hidden effect in a class through its access of a global or a collaborating object, passing its reference into the class makes it testable. Pure functional programming gives you this by default.
Most of the issues I run into involve the grain of complexity: how do we make pieces that are the right size to inspect or test and compose them so that the same is true.

Matteo: A big point mentioned in your book is characterization testing.
What’s your view on test refactored code directly in production alongside the actual code through live result comparison as opposed to the classic way of writing characterization tests? Can the former substitute the latter?

Michael: I think that they are different tools for different situations. I like live comparison. Although it can’t give you absolute assurances that two pieces of code behave the same way, it can have the benefit of giving you information about how much the code is used as well. That can help you make a risk assessment about when to switch over.

Matteo: One of the topics you’ve been dealing with in your blog is Repository Analysis as a means to collect data about the code base. How can we use such wealth of data to guide us through discovering what areas of your code are more impacted from technical debt and more interesting in terms of business value?

Michael: I’ve moved away from that space a bit, not because of lack of interest but rather lack of time. I recommend Adam Tornhill’s work in that space – his books “Your Code as a Crime Scene” and “Software Design X-Rays.”
I also recommend Janelle Klein’s book “Idea Flow.” Rather than repository analysis she advocates recording the experiences of people as they work and using them to focus system’s improvement. Adam and Janelle have complimentary approaches that are important contributions to that space.

Matteo: You’ll be teaching a workshop titled “Working Effectively on Legacy Code” in Milan on November 5-6 this year. Will any of the above points be dealt with during the course? What will the main focus be? Tell us something we don’t see in the course description and… make us curious to read more and, eventually, to join you! 🙂

Michael: Yes, I’ll be discussing many of these topics.
Hmm… not in the description… I think that two things attendees can expect are some material related to rewriting code and material related to changing the interface between business and development so that we don’t incur technical debt at all.
I hope that sounds intriguing.

Matteo: What could be a nice and fitting soundtrack to this workshop?

Michael: I’m a fan of complicated music and very skilled musicians, which is a bit odd since I don’t like complicated code. Since this is my first time to mainland Italy, I pick the track Gravita 9.81 by the Italian band Arti E Mestieri. I wonder whether any attendees know of them?

Matteo: That was an interview! 🙂 Thanks Michael, and see you soon! You can close anyway you like.

Michael: Wow. We’ve talked about so much. I guess I’ll just close by saying I’m really looking forward to this training. See you all soon!

Pics credits: Ed Telling, Skills Matter, Alexandre Perotto, Manish Kumar, Unsplash.

More on Avanscoperta

Check out our upcoming workshops: Avanscoperta Workshops and Training courses.

Get our updates, a hand-picked selection of articles, events and videos straight into your inbox... Once a week!
Subscribe to Avanscoperta's Newsletter (available in Italian and English).