All episodes
Episode 88 · Jun 13, 2023 · Talk

Kevlin Henney on Code Refactoring

Featuring Kevlin Henney, Consultant, Trainer and Author
Apple Podcasts Google Podcasts Spotify Youtube

Refactoring has become an integral part of software development practices and has gained widespread recognition and adoption in the industry. It promotes clean code, extensibility, and readability, as the pillars of robust and easier-to-maintain software systems. But as the concept of refactoring continues to evolve as new programming paradigms and technologies emerge, its role as a teaching tool should be preserved. In this episode, we explore code refactoring through the perspective of Kevlin Henney, an experienced consultant, trainer, and co-author of renowned programming books. Learn how his insights shed light on the importance of refactoring as a design practice and the impact of time pressure on code quality.

Edited transcription

In the design, writing, and implementation of code, bugs are not the only potential defective outcome. Problems or shortcomings can arise due to code hard to understand or modify, to the point of negatively impacting the overall quality of software. Legacy and rushed code are prone to issues of this kind.

In this regard, code refactoring consists of subjecting code to a closer inspection to find signs of potential improvement in terms of readability, maintainability, or performance, and restructuring it without changing the software’s external functionality. The goal of refactoring is to enhance the quality of the code by addressing issues such as code duplication, complex logic, poor naming conventions, and excessive dependencies and applying established software engineering principles and best practices.

Software Consultant and Author Kevlin Henney is known for advocating the practice of code refactoring as a means to achieve better software quality and to continuously improve codebase design. He emphasizes the importance of refactoring as an integral part of the software development process and considers it a crucial skill for developers to integrate into their craft and master.

Learning through code refactoring

The idea of code refactoring has transformed over the years. As Kevlin recalls, the term legacy code had only just been coined when he got his first job. This didn’t mean that there wasn’t legacy code, nevertheless. He saw lots of duplication in the existing code base, as well as cases where “the logic had obviously evolved” and yet the code remained unattended. Refactoring (or factoring as he called it at that time) started for Kevlin as a way of “taking a complex piece of logic and just simplifying it” and evolved as a way of putting code that works in good shape to make it more understandable.

On the other hand, Kevlin confidently judges refactoring as a “first-class design practice.” “The first attempt that you do something is probably the first time you do something,” says he, understanding that code, despite how much effort you put into it, will not be perfect in its first iteration. Still, it is possible to fix the code afterward. Knowing this, says Kevlin, releases “deadline pressure” from the initial coding, in which it is possible that “the technology is new, the requirement is new, the team is new, all of these things are new.”

Besides, as time goes by and teams familiarize themselves with the project, they learn more and will have less trouble fixing the code and adapting it to new, better design decisions. In this way, Kevlin understands, “[refactoring] allows you to update continuous accumulation of knowledge that can be incorporated into your code base.”

However, according to Kevlin, the idea of fixing code to understand it better is being lost. Primarily, due to automated refactoring tools, which prevent the close inspection of manual intervention from happening. For this reason, Kevlin advocates in favor of code refactoring as a learning experience for developers to expand their knowledge and improve their coding skills. Through refactoring, developers have the opportunity to review and analyze existing code, understand its intricacies, and identify areas for improvement. Overall, the process enhances their understanding of the codebase, the underlying design principles, and the overall system architecture. What’s more, since refactoring often involves researching and implementing best practices, developers end up internalizing them.

Balancing pressure and code quality

From a broader perspective, Kevlin affirms that taking better decisions demands reflecting, something that can only occur if you take the time to stop and have a look at the work you have done. Yet, he admits that this idea conflicts with the pace at which the software industry is usually run. “Move fast and break things”, Kevlin points out, leading to a fixation on fast deliveries that is prone to make us focus on metrics, preventing us from discerning between calm and intense periods of work and, more importantly, making us lose track of what we want to achieve. “We are getting people incredibly busy and we’re getting really good at building the wrong thing in the wrong way rather than moving in the right direction,” he claims.

The pressure of deadlines would be justified, says Kevlin, if it “actually gave us the things that we were after;” instead, he finds that “we just end up with a lot of urgency” while “the quality of the code is not necessarily improving.” Consequently, Kevlin believes the focus should be on “the amount of functionality,” which “is not independent of the way that we express it,” that is, the code itself. Hence, rather than prioritizing other tasks over code quality, it is necessary to recognize that these other tasks, as in the case of developing new features or functionality, probably rely on code.

Challenging scaling practices: value demand and failure demand

From this perspective, Kevlin challenges companies’ scaling, and asks rhetorically “Why have you got twice as many developers? Is it because you are producing twice as much value, or is it that the other developers are now dealing with the problems the first developers created?

Likewise, Kevlin encourages developers to ask themselves if the work they are doing is “in response to other work that I didn’t do? Is the reason that I am busy today because of something else I could have learned from and didn’t?” He brings up the fact that software teams are frequently made of people with different levels of experience and, consequently, different notions of the ideal way to approach a given problem. If you think of developers as a knowledge base, “the knowledge that you need is probably in somebody else’s head,” he says. However, as a way of learning about your own work as a developer, Kevlin recommends “finding the opportunity to look at what you’re doing and reflect on it; at any particular point, that may tell you things that you need to know, but even things that you don’t want to know.”

At a collective level, “most people are working because something else is not working”, says Kevlin, while bringing the concept of value and failure to measure where the company’s efforts are directed and understand how much of their efforts are toward “meaningful work”. Value demand refers to the customers’ legitimate requests for software features, functionalities, or solutions that provide them with value, address their needs, and contribute to their overall satisfaction. In turn, failure demand arises when customers encounter issues, bugs, or deficiencies in the software that require additional support, maintenance, or rework.

In this way, fixing bugs, at most, “removes that loss of value, but we’re not actually achieving something new,” says Kevlin. In like manner, developers might spend a large bunch of their day trying to figure out what code they need to become more familiar with. Kevlin estimates “that for most developers, no more than about 10% of any week is spent actually adding meaningful value to a system”, meaning that “10% of developers are doing meaningful work” while “the other 90% are dealing with the problems that everybody has created and either through no fault of their own, sometimes through lack of knowledge, but also the way that they work, the workflow they have, the company culture that they have.

To balance things out, Kevlin recommends bringing awareness to unmanaged and managed technical debt. Technical debt refers to the practice of postponing code development to release a product or feature early. He points out that development doesn’t have to be perfect; in fact, it can be rushed to deliver in some cases. However, acquiring technical debt has to be a conscious decision, not accidental or neglected, and it has to be managed properly. Still, postponing development can help to make better decisions. After delivery, developers have more knowledge of their work; besides, early code is where teams might choose to experiment with approaches and technologies that could be ditched in the future.

The bottom line

You can follow Kevlin on Twitter, Linkedin, and Mastodon. As part of his job as an independent consultant, Kevlin Henney gives workshops, seminars, writings, conferences, and training. He has put together a Youtube playlist with his many interviews and talks about software development, including his talk Refactoring is Not Just Clickbait where he addresses the milestones in the history of refactoring. Kevlin also blogs on Medium.

Kevlin has co-authored many books, including 97 Things Every Programmer Should Know and 97 Things Every Java Programmer Should Know.

Leave a Reply

Your email address will not be published. Required fields are marked *

Meet the host

Darko Fabijan

Darko, co-founder of Semaphore, enjoys breaking new ground and exploring tools and ideas that improve developer lives. He enjoys finding the best technical solutions with his engineering team at Semaphore. In his spare time, you’ll find him cooking, hiking and gardening indoors.