Shotgun surgery

Source: Wikipedia, the free encyclopedia.
This visualizes a shotgun surgery
A shotgun surgery can also be when a change to a "Class A" causes several minor changes to other classes in a software system.

Shotgun surgery is an

refactor) a system to support the new features trivially. As a consequence, the practice of copy-and-paste programming
is prevalent; the code is written in a single place then simply copied to all other places where that implementation is required (with any required changes applied in-place).

This practice is generally frowned on by the refactoring community as a direct violation of the abstraction principle, also known as the Once and Only Once rule – ultimately any change to the new functionality may require widespread changes. Further, any potential software bug in this new feature will be replicated many-fold and can make bug fixing particularly difficult and tedious. Even in the absence of copied code, the implementations are guaranteed to be very similar and just as prone to requirements change or bug fixing. This form of software development tends to favour short-term improvement (in the form of additional features) at the cost of long-term maintainability and stability.

Example

The canonical example of this practice is logging which generally adds prologue code to many functions simultaneously, for example:

void Func() {
  ...
}

void Func2() {
  ...
}

...

void FuncN() {
  ...
}

Could be transformed to:

void Func() {
  printf("Entering Func\n");
  ...
}

void Func2() {
  printf("Entering Func2\n");
  ...
}

...

void FuncN() {
  printf("Entering FuncN\n");
  ...
}

Here a single requirement has added similar code to several functions simultaneously. As such any change in requirements here (namely adding line numbers to the log) would now require a considerable effort. Shotgun surgery is not synonymous with cut and paste coding, as highlighted by this trivial example. The practice of copying code can be viewed as a "means to an end", where shotgun surgery is merely an "end" (i.e. there are many ways to reach the same conclusion).

Consequences of shotgun surgery

The concerns with this style are by-and-large the same as those for any duplication in a software system; that is, duplicating the same logic in many places can vastly increase the costs of making changes to the same logic later. Some of the aforementioned costs are measurable, others are not (at least not trivially). There is also some evidence that this anti-pattern is correlated with higher defect rates.[1]

Typically some combination of the following is to be expected:

  • Increased developer effort and reduced throughput
  • Associated monetary cost of the above (as in commercial development)
  • Psychological effects and potential neglect of code

Of these the most insidious are the psychological effects (e.g. see broken windows theory) which can exponentially lead to software rot.[citation needed] When uncontrolled this can cause entire codebases to become unmaintainable. Generally the only solution to this problem is to completely rewrite the code [citation needed] (at substantial cost).

Mitigation

Aspect-oriented programming (AOP) aims at reducing these forms of invasive modifications in favour of adopting an "aspect" or "concern". The solutions take the form of boilerplate code which can be applied over a domain of functions simultaneously (through the process of weaving) which vastly reduces the amount of duplicated code. The use of domain-specific languages is also becoming more widespread where light-weight compilers are written to generate most of the duplicated code on the behalf of the programmer. Both methods fall into the broader categories of code generation and automation.

See also

References