Symptom

A class carries several near-identical methods that differ only by a single literal — a field name, a constant, a threshold. The duplication is mechanical; the methods change in lockstep; the class grows linearly with the number of variants supported.

Goal

One parameterized method replaces the N variants. What varies between them becomes an explicit argument; what stays the same lives in one place.

Before the refactoring

// Three near-identical methods, differing only by which book field they search.
class BookSearch {
constructor(repo) {
this.repo = repo;
}
searchByAuthor(query) {
return this.repo.where(book => book.author.toLowerCase().includes(query.toLowerCase()));
}
searchByTitle(query) {
return this.repo.where(book => book.title.toLowerCase().includes(query.toLowerCase()));
}
searchByPublisher(query) {
return this.repo.where(book => book.publisher.toLowerCase().includes(query.toLowerCase()));
}
}

After the refactoring

// One method; the varying field is a parameter.
class BookSearch {
constructor(repo) {
this.repo = repo;
}
searchBy(field, query) {
return this.repo.where(book => book[field].toLowerCase().includes(query.toLowerCase()));
}
}
Example source: Illustrative example written for this site, adapted from Kerievsky's pattern description in Refactoring to Patterns (Addison-Wesley, 2004), chapter 6. The book frames Extract Parameter as the structural move that prepares a method for Form Template Method by isolating what varies between near-duplicate methods.
Pressure

Each duplicated method must be maintained, tested, and documented separately. A bug in the iteration semantics requires N edits; adding a new variant means another near-copy, not new logic. Reviewers must scan all N methods to confirm they stayed consistent.

Tradeoff

Parameterized methods can become call-site noise — the caller now passes a string or constant whose meaning isn't clear from the call site (`searchBy('author', q)` reads worse than `searchByAuthor(q)`). For two or three variants with stable, semantically distinct names, separate methods may be more intention-revealing.

Relief

Bug fixes land once; new variants are zero new code at the class level; tests cover the parameterized method once and trust the parameter to do its job. The class's surface contracts to the actual behaviours it offers.

Trap

A parameter that is really a type code — `searchBy(field, q)` where `field` must be one of three strings — replaces compile-time clarity with runtime stringy-ness. Past a small number of values, this is a signal to reach for Replace Type Code With Class or Strategy.