Copy-Paste Programming
Copy-Paste Programming duplicates code instead of factoring shared logic, so fixes are repeated, missed, and copies diverge. Follow DRY: extract common logic into one reusable unit and parameterize the differences.
Copy-Paste Programming is building functionality by duplicating existing code and tweaking the copy, rather than extracting and reusing shared logic. The same block — a validation routine, a data transform, an error handler — appears in many places with slight variations, each a fork of the original.
Why It Happens
Copying is the fastest way to get something working that resembles existing code. Reuse requires designing an abstraction, which feels slower under deadline pressure. Developers unfamiliar with a codebase clone a working example rather than learn the shared utility. Pressure to ship and weak code review let duplicates accumulate until they are everywhere.
Why It Hurts
Every bug and requirement change must be applied to all copies, and inevitably one is missed, so the copies diverge and behave inconsistently — a fix in one place silently leaves the others broken. The codebase bloats, increasing the surface to read, test, and maintain. Duplicated logic also hides intent: it is unclear whether two near-identical blocks are meant to stay identical. Over time the copies drift apart, and what should be one rule becomes several subtly different rules.
Warning Signs
- Large near-identical code blocks across files (clone detectors flag these).
- Fixing a bug in one location while the same bug lingers elsewhere.
- New features built by copying a similar feature and editing it.
- Inconsistent behavior between parts of the system that 'should' match.
Better Alternatives
Follow Don't Repeat Yourself: each piece of knowledge should have one authoritative representation. Use Extract Method (and extract class/module) to factor shared logic into a single reusable unit that callers invoke. Promote genuinely cross-cutting logic into reusable libraries or shared modules. Parameterize the small differences between copies so one implementation serves all cases. (Beware over-abstracting truly coincidental duplication — extract when the duplication represents the same knowledge.)
How to Refactor Out of It
Use a duplication detector to locate clones. For each cluster that represents the same knowledge, extract the common part into a single function, class, or module, expressing variations as parameters or strategy objects. Replace each copy with a call to the shared unit, one at a time, keeping tests green. Centralize any duplicated constants and validation. Reconcile drift you discover between copies into one correct behavior, adding tests to lock it in. Add review and lint gates to discourage new clones.