Software developers have few fears, but mention legacy code and most will start to break out in a cold sweat; others will have lots of war stories to share. David Scott Bernstein has published Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software.I caught up with David to find out more about the book, and how it helps arm developers with a set of practices that supports software from becoming legacy code so it’s more cost-effective to maintain and extend.
DZone: Can You Introduce Yourself to Our Readers Please?
David: I'm David Scott Bernstein. I've been a software developer and consultant for the last thirty years. Over the last twenty-six years I've trained professional software developers in new development paradigms. In the old days it was GUIs and OO. Today it's Agile developer practices such as TDD, refactoring, and emergent design. I've trained over 8,000 professional software developers in my career and I get to learn as much from my students as they do from me.
Through my consulting company, To Be Agile, I offer Scrum Developer Certification and non-certification training, coaching, and consulting for software developers and development teams. My focus is on the technical practices of Extreme Programming including test driven development, refactoring, and emergent design.
DZone: What's the Driving Force Behind Your Book, Beyond Legacy Code?
David: I saw a lot of attention being paid to the Agile processes for ScrumMasters but not a lot of attention to Agile developer practices. The Agile Manifesto was created by software developers for software developers and I believe the highest value practices for Agile software development are the technical ones.
The main reason I see that teams are not adopting the technical practices, or adopting them without getting the benefit they had hoped for, is they don't yet understand the purpose behind the practices, and therefore don't apply them well. I wanted to write a book that focused on nine core practices and why they work so that people could understand their value and how to apply them correctly.
Interestingly, because I'm discussing the purpose behind the practices and why they work, this book is valuable to both software developers and the non-technical members of our teams. When I started out to write this book I didn't think it would be possible to speak to both audiences but since all the technical practices boil down to common sense, I've found ways of describing them that are easy to understand.
In the first part of the book, I discuss what I call the "legacy code crisis" where it's estimated that up to $60 billion annually is lost on broken software development processes. The way we traditionally build software is hugely inefficient and fraught with risk. Even with Agile overtaking Waterfall software development, the odds are still less than 3 to 1 that a software project will be successful. But it doesn't have to be that way.
The remaining four-fifths of the book offers solutions by focusing on nine essential practices for building testable behaviors in code. These nine practices are: Say What, Why and for Whom Before How; Build in Small Batches; Integrate Continuously; Collaborate; Create CLEAN Code; Write the Test First; Specify Behaviors with Tests; Implement the Design Last; and Refactor Legacy Code.
These nine practices help focus development to build valuable pieces of verifiable software. It supports us in building code so it's understandable and straightforward to work with in the future. It's about adopting some basic standards and practices that support building maintainable software.
DZone: Are All These Practices Geared Around Writing Code That Lasts Longer?
David: Yes, software must provide value now and in the future. Since the user's needs are likely to change, it means the software is likely to change as well. These nine practices help us build testable behaviors that cost less to extend and therefore last longer in the field.
Since 80% of the cost of software happens after the initial release. Even minor additions to existing software cost more than twice as much as it costs to initially write it. This is because as an industry we don't write code that's easily changeable. Too many of us treat software as a write-once activity but in reality software is a write-many activity and the software we write has to be able to accommodate change.
DZone: Could You Give Us a Short Synopsis of One of These Practices?
David: Sure, the first practices is "Say what, why, and for whom before how." This applies to all requirements regardless of whether it's in the form of a specification, use case diagram, or even in the conversation between the Product Owner and developer.
We speak and understand procedurally, in terms of implementation. This is how spoken language works. But this is not the best way to express how to build software. Instead, discuss goals and objectives, what you want accomplished, and what are the challenges and constraints.
By focusing on what the user wants and why they want it, we can often build a better system for the user and do it in a way that’s more maintainable and easier to work with in the future.
DZone: What Can You Do When You Take Up Some Legacy Code Without Any of the Previous Authors Around?
David: The first and most important step when working with legacy code is to understand it. This is also often the hardest step and the one we have least to show for. But all other work with legacy code depends on this first step--understanding it.
Michael Feathers in his book, *Working Effectively with Legacy Code*, suggests a subset of refactorings from Martin Fowler's book, *Refactoring* that are relatively safe and can be used to embed learning in a system. For example, wrapping a poorly named method with an intention revealing name or creating seams to inject dependencies and add in unit tests.
Refactoring legacy code is actually a valuable skill. Not only will it put you in high demand, because there's a huge demand for this kind of work, but also by fixing other people's code it stops you from making the same mistakes and you end up writing much better code yourself.
DZone: What is Your Key Piece of Advice for Those Who Inherit Legacy Code?
David: "If it ain't broke, don't fix it."
Legacy software is more like landmines than time bombs. If software works and doesn't need to be changed then don't mess with it. We refactor legacy code to drop the cost of adding features. If you don't need to add features to legacy code then you probably don't need to refactor it.
But if you do need to add features and change existing code then it's easier, less risky, and more cost-effective to first refactor the code so it can easily accommodate that change and then add the feature with minimal changes to the existing system. Implementing features in the two-step process is safer and faster than trying to do these two steps at the same time.
People think Agile development is an undisciplined, shoot-from-the-hip approach but nothing could be farther from the truth. Because Agile removes many of the checks and balances of traditional Waterfall development so developers can spend their time developing, it requires a great deal of discipline to pay off technical debt and keep code quality high.
Teams that don't pay attention to code quality iterate into garbage. Teams that do pay attention to code quality iterate into elegance. It all hinges on understanding why the practices work and that's precisely what my book stresses. You can learn more about my book, read excerpts, watch a video, and buy a copy at http://BeyondLegacyCode.com.