A Development Team Experience: How Dependency Mapping Could Have Saved Us (Part 1)
A Development Team Experience: How Dependency Mapping Could Have Saved Us (Part 1)
Two years of hard work went up in smoke with a single email. Customers would never see the product.
Anyone who is in the business of software development can recall the project that failed in spectacular fashion. For me, it was a project to rewrite an existing product that had become too difficult to work on by the development and product teams. I can still remember when we made the decision to stop development. I was a Product Owner at the time. The Product Manager and I discussed the pros and cons of continuing the rewrite project and what it would take to get the product customer-ready. Unfortunately, the list was extensive and internal support for the project was waning. The decision was difficult but had to be made. We spent two years rewriting the product but were no better off than when we started. Looking back, I can’t help but wonder if we made the best decision. Should we have refactored instead?
Rewrite or refactor?
This story began two years prior to that email. The first version of our product had been in customers’ hands for several years and, for the most part, they were happy. We had built a reliable product that solved a real problem for users. But as time went on, our ability to add new features slowed down to a near standstill. Customers began reporting bugs. Roadmaps were extended to add buffer time to delivery estimates. Revenue began to flatline. Something had to be done.
A strategy meeting was organized. The whole team, including product managers, developers, and leadership discussed the delivery problems. As we discussed our options, two camps emerged: those in favor of rewriting and those in favor of refactoring. The lines were clearly drawn and neither side could be persuaded easily.
Over the course of several weeks, the development team wrestled with the vague, but critical question of rewriting or refactoring the code. This was no easy task. Version one of the product had been in active development for four years, which meant the code had evolved dramatically over time as different developers added and changed code. We broke into small groups to discuss specific problem areas and identify the underlying causes of the delivery issues.
Be wary of tribal knowledge
As a member of the product team, I wanted to focus on key areas of the application that were highly used, but prone to bug reports. When we attempted to review certain parts of the application, we found ourselves constantly seeking input from a few key team members. “Ask Dave” was a typical response to my inquiries. Why? Because Dave was a senior developer on the team and had written much of the code. If he didn’t write it himself, he was either consulted or had a hand in the code review. Asking the senior team member is often referred to as “Tribal Knowledge” because the information lives in someone’s brain and not on paper.
One aspect of tribal knowledge to recognize is that the quality of the knowledge degrades over time. As team members leave and new members join, the definition of the “most senior” developer changes. In my scenario, there should have been an urgency to answer the question “What if Dave leaves?”
As the senior title is passed along instead of asking the developer who wrote the original code, you may be asking the developer who has had to maintain it the longest. Just as in the judicial court system, eyewitness testimony should be taken with a certain level of skepticism.
Complexity is often subjective
Many of the questions I asked our developers were answered with very dramatic reactions. I can recall asking a developer about a specific feature that was central to the success of the product. Because the feature was used often by customers, we had invested considerable time and effort to improve the implementation. The developer had spent hours refactoring the code many times. When I asked his opinion about rewriting the code, he threw up his hands and simply said it would be “too hard.” He knew that specific part of the code was complicated. He also knew the task of rewriting the code wouldn’t solve the issue. In fact, there was no guarantee that the new code would function any better.
To make matters worse, other developers on the team wouldn’t contribute their own opinions because they never worked on that part of the code. Anytime we had worked on that part of the application, it was completed by the single developer who understood it the most. We had become overly specialized. Other developers weren’t confident they understood the code or could make changes safely.
As a result, we continually found ourselves making vague assertions about the complexity of the code with statements that couldn’t be measured, quantified, or easily explained. When a complex part of the application was brought up, the audible sighs that came from around the room were deafening. Everyone KNEW that those areas of the code were complex, but they couldn’t explain why or how to begin addressing the underlying reasons.
The power of code dependency mapping
Many of the reasons we decided to rewrite the product came from gut reactions as opposed to tangible data points. Unfortunately, it took months before our team fully understood the complexity of the problems we were up against. We spent more development time and money than needed to get the project off the ground.
Looking back, an automated code dependency mapping tool would have helped us manage our code complexity from the beginning. Perhaps we could have avoided the whole rewrite versus refactor decision to begin with. Even if that inflection point in our business was inevitable, an automated code dependency mapping tool would have helped our team make a decision rooted in facts, not tribal knowledge or emotion.
All in all, if we had the ability to see our code connections we would have done things differently – from our efforts to write code that wouldn’t break things to our decisions about paying down tech debt.
In part 2 of this blog, I’ll share more thoughts on how I believe code dependency mapping could have helped our (or anyone else’s) team.