# Change Preventers

> Smells where one change forces edits in many places, or one class changes for many unrelated reasons, making every edit slow and risky.

- kind: category
- category: refactoring
- canonical: https://aipatterns.dev/refactoring/smells/change-preventers
- inspired-by: https://refactoring.guru/refactoring/smells/change-preventers

## What these smells share

Change preventers show up in the commit history more than in any single file. You notice them when a small feature takes a day because it touches ten files, or when one class appears in every pull request regardless of topic. The structure of the code does not match the axes along which requirements change.

The fix is to regroup code so that things which change together live together, and things which change for different reasons live apart.

## Members

- [Divergent Change](https://aipatterns.dev/refactoring/smells/divergent-change.md): one class is edited for many unrelated reasons, such as both database changes and pricing rules.
- [Shotgun Surgery](https://aipatterns.dev/refactoring/smells/shotgun-surgery.md): one logical change requires small edits across many classes.
- [Parallel Inheritance Hierarchies](https://aipatterns.dev/refactoring/smells/parallel-inheritance-hierarchies.md): every new subclass in one hierarchy needs a matching subclass in another.

## How to choose within this category

- Divergent Change and Shotgun Surgery are mirror images. Ask which way the change spreads.
  - One class, many reasons to change: [Divergent Change](https://aipatterns.dev/refactoring/smells/divergent-change.md). Split the class.
  - One reason, many classes to change: [Shotgun Surgery](https://aipatterns.dev/refactoring/smells/shotgun-surgery.md). Gather the pieces.
- If the scattering follows a pair of class hierarchies that grow in lockstep, it is the special case [Parallel Inheritance Hierarchies](https://aipatterns.dev/refactoring/smells/parallel-inheritance-hierarchies.md).
- Use version control to confirm. Files that are always committed together point to shotgun surgery; a file touched by every unrelated change points to divergent change.

## Typical treatments

- [Extract Class](https://aipatterns.dev/refactoring/techniques/extract-class.md) to split a class along its reasons to change.
- [Move Method](https://aipatterns.dev/refactoring/techniques/move-method.md) and [Move Field](https://aipatterns.dev/refactoring/techniques/move-field.md) to gather scattered behavior into one place.
- [Inline Class](https://aipatterns.dev/refactoring/techniques/inline-class.md) when a scattered concern ended up in many tiny classes.
- Move Method and Move Field to fold one parallel hierarchy into the other.

## For agents

- Do not over-correct. Splitting a class for every possible reason creates shotgun surgery; merging everything to avoid it creates divergent change. Group by the changes you have actually seen.
- Check the git log for co-change patterns before restructuring. It is better evidence than reading the code.
