What is Shotgun Surgery?
Let’s start with something that most developers can relate to - we unintentionally incorporate code smell into our code, which makes our design vulnerable. In programming, code smells, also known as nasty smells, refer to any symptom in the source code of a program that may signal a larger problem.
In this post, let’s look at a type of code smell called shotgun surgery, along with its uses and benefits.
Table of contents
- What is Shotgun surgery?
- Problematic scenarios
- The necessity of Shotgun surgery
- How to fix the problem?
What is Shotgun surgery?
As pointed out above, shotgun surgery is a specific type of code smell in your codebase that occurs when a large number of changes to your codebase are required to accomplish seemingly basic tasks. Frequently, you'll find yourself making modifications to code that appears to be quite similar, either because it was copied straight or because the goal is similar.
Before we get into the details, let's understand why it's called shotgun surgery. Consider a routine surgical procedure. You think of precision and least invasiveness when you think of a surgeon doing an operation. They go in with scalpels and only do what is necessary.
Consider what would happen if that procedure was replaced with a shotgun. Shotguns work by shooting projectiles that spread over a short area, essentially blowing holes in everything in their path. As a result, a "shotgun operation" is the most invasive surgery possible—almost the epitome of overkill when it comes to surgery. Shotgun surgery is intended to portray a codebase that forces a messy, error-prone approach over a precise one.
Following are a few of the causes of shotgun surgery smell:
- Due to a lack of worry separation.
- Failure to use the correct design pattern.
- Failure to grasp the gravity of the situation. Frequently, this is due to a misunderstanding (Single responsibility principle).
- Not recognizing common conduct or behavior with a minor variation.
Shotgun Surgery's Consequences:
- There are numerous code duplicates.
- Investing more time in the development of a minor feature.
- The codebase is unmaintainable.
Following are few scenarios which will make you understand the need for Shotgun surgery:
Scenario 1: First and foremost, have you ever encountered a codebase that separated things to the nth degree? It might have a class for all constants and a class for static variables. Perhaps it also has a location where you can define all menu items, as well as a place where you can define their subsequent actions.
What's the end result? Every time you want to add a menu item, you must first declare the menu item text in Constants.cs, and then define all of the delegates that handle menu item clicks in another class. You'll need to make adjustments in a third place to add the menu item to the GUI, as well as a fourth place to attach the delegate to a specific action. For a single conceptual change to your software, that's a lot of changes.
Scenario 2: Speculative over-architecting is another prominent example. Have you ever encountered a codebase that defined numerous layers, replete with data transfer objects, data access objects, domain objects, and so on, to manage a simple CRUD app? In addition to the different property bag objects within those layers, every time you want to add a table to the database, you now have to install scaffolding across all four tiers? This is another case of shotgun surgery.
Scenario 3: Then there's the easiest example. Updating a codebase by copy-pasting code everywhere. This means that if you change some of the copy-paste code, you'll have to repeat the process for each subsequent incarnation.
The necessity of Shotgun surgery
Now that you know what shotgun surgery is, you might be wondering what causes it. How did codebases end up in this state?
Let’s pick the scenario of copy-paste programming. When people are in a rush or don't know any better, they copy and paste code. This results in knowledge duplication throughout the codebase, adding to the maintenance overhead.
The issue of lack of cohesion in your codebase is amplified through copying and pasting. Cohesion refers to both a specific measure computed by NDepend and a broader concept. Consider the following general concept for our purposes: do things that belong together happen together?
Highly cohesive codebases follow the single responsibility principle, which states that each unit of code should have only one reason for changing, and that reason should be the sole reason. Beyond that, they try to keep changes as local as possible. Shotgun surgery is performed when your codebase becomes non-cohesive due to any reason.
How to fix the problem?
The first step is to make a list of all the changes that have been made to your codebase. Audit your source control tool, or keep track of how many files you're handling while making theoretically basic changes in your head. If it's a lot, you've got a problem.
A healthy codebase is one in which you're building minor features with only a few source files updated. You may end up handling many major modifications, but not the entire codebase or even a significant portion of it. Localizing modifications should be a top priority when it comes to code maintenance.
And if you're copy-pasting code, you've got a problem. Use a duplicate code detection tool to find it. For example, NDepend includes a powerful duplicate code identification tool.
You'll never be able to create the ideal design. Separating multiple elements apart might always look sensible, and even seem like it’s the best play. However, if you find yourself in a shotgun surgical situation, you must accept that the environment around you has changed and evolved, and you must adapt. Arguably, the most effective thing you can do is simply be mindful of the odor while working. Find out if your maintenance programmers need a shotgun or a scalpel to implement changes in the future. If the answer is "shotgun," you should rethink your strategy.