Recently, I wrote a blog about shotgun surgery. I talked about how the shotgun surgery code smell works. If you aren't familiar with it, go and check out that blog post.
I like keeping these emails fairly short and digestible, but there's a bit more I wanted to discuss about this code smell, and how it relates to the process of growing your architecture.
When we discuss software craftsmanship, such as code smells, we are working on keeping our code maintainable. This is a bottomless pit of effort. Ultimately we could spend years just perfecting code without ever adding new capabilities or features. It's the classic struggle between maintainability and over-engineering (which is a code smell itself). We can craft, and polish, and refactor, and re-architect, and make our code more and more beautiful. But at some point, we're wasting our time and should be doing something else (probably building more features).
So where do we draw the line? How do we know when to stop? How can we decide what is good engineering, and what is over-engineering? What objective criteria can we use?
It comes down to knowing what parts of the code to spend your time on, and here comes some of the art of programming: where is code likely to change? Craftsmanship improves maintainability. Maintainability is about changing code in the future. So if we know what code will change in the future, and how and why, then we know where to focus our efforts today.
That's why shotgun surgery is a code smell. It is about the cost of making a change in the future. So knowing that a change could be made lets us address the issue today so that the changes (surgery) we make tomorrow are easier (or even possible).
If you know for sure that a particular tax calculation will be changing next year, then you should make sure that the relevant section of the application is easy to change, and therefore you will spend extra time crafting that part of your system.
Therefore, the time you spend considering the likelihood of change in a particular part of your system is time well spent. It gives you insight into what parts of the application should receive more focus. Never neglect parts of your system, but spend the extra time on the places that have a high likelihood of change.
Identifying these places will often come from experience as a software developer. It will also come from domain knowledge about what you're building. It will come from understanding your backlog and what features may be built in the future. But there are certainly a few places that are more than likely to require change over time regardless of the above. So here are a few places you should highly consider spending extra time:
- Interfaces with external systems
- Interfaces with other internal systems
- Interfaces between tiers of the existing system
- The user interface, especially core functionality that is important to your users
These are areas that are likely to change, and likely to change frequently. So make sure they aren't full of cobwebs.
Ultimately there's no crystal ball, no way to peer into the future. So keeping your entire code base well maintained is still the right answer. Every time you ignore a code smell, you are borrowing from tomorrow to pay today. Don't let that get out of hand.
What likely places of change did I miss?