Compare
Symptom
Human

Two or more classes in the codebase do similar work but use different method names, parameter shapes, or return types for the same operation. The divergence is accidental — they were written at different times by different people. Callers can't treat them uniformly; tests for each one duplicate setup; cross-class refactoring requires synchronized edits.

Agent

Operations with the same semantics carry different names across N classes; a grep for one name returns one class's call sites, missing the aliases; the agent enumerating consumers pays the cost of knowing the alias map for the operation.

Goal
Human

All variants share one method-name vocabulary for the same operations. Callers operate against either interchangeably; tests can share helpers; future variants land with the same vocabulary.

Agent

Each operation has one name across every class that exposes it; a grep for the name returns every call site, and the agent enumerates consumers without paying for an alias map.

Before the refactoring

// Two repositories do the same work with accidentally divergent names.
class UserRepository {
findOne(id) { /* ... */ }
insert(user) { /* ... */ }
updateById(id, fields) { /* ... */ }
remove(id) { /* ... */ }
}
class OrderRepository {
getById(id) { /* ... */ }
create(order) { /* ... */ }
update(id, fields) { /* ... */ }
delete(id) { /* ... */ }
}
function loadEntity(repo, id) {
if (repo instanceof UserRepository) return repo.findOne(id);
return repo.getById(id);
}

After the refactoring

// One method name per operation; both repositories conform.
class UserRepository {
findById(id) { /* ... */ }
create(user) { /* ... */ }
update(id, fields) { /* ... */ }
delete(id) { /* ... */ }
}
class OrderRepository {
findById(id) { /* ... */ }
create(order) { /* ... */ }
update(id, fields) { /* ... */ }
delete(id) { /* ... */ }
}
function loadEntity(repo, id) {
return repo.findById(id);
}
Example source: Illustrative example written for this site, faithful to Kerievsky's pattern shape in Refactoring to Patterns (Addison-Wesley, 2004), chapter 6. Distinct from Unify Interfaces With Adapter (#26): that pattern is for when you cannot edit one of the classes (typically a vendor); Unify Interfaces is for when both classes are yours and the divergence is accidental.
Pressure
Human

Accidental interface divergence is a tax on every consumer that handles both. The divergence often grew from copy-paste with renames; each rename created another inconsistency to navigate. Reviewers and agents must remember which class uses which name.

Agent

Inconsistent naming forces the agent to enumerate aliases on every cross-class change. The cost compounds — `find usages` returns partial results; semantic edits miss aliased variants; the agent's confidence in completeness drops.

Tradeoff
Human

Renaming methods is a wide ripple — every call site moves. For classes with public APIs or vendor consumers, the breaking-change cost may exceed the consistency gain. Sometimes a single adapter call site is cheaper than a rename across N consumers.

Agent

Renames break external consumers who depend on the old names; the agent must verify the rename's blast radius before applying it. For library code with documented APIs, the rename cost may exceed the consistency gain.

Relief
Human

One vocabulary, one call shape, one set of tests' helpers. Future variants land with the established names; new consumers don't have to learn which-name-here-and-which-name-there.

Agent

Edits to the operation's contract land against one name across every class; tooling that searches by name returns every call site, and the agent does not pay the alias-mapping cost on cross-class changes.

Trap
Human

Forcing two genuinely-different operations onto the same name to satisfy the pattern produces silent behavioural drift — the names match but the semantics differ. Unify Interfaces is for accidental divergence; if the operations actually behave differently, they should keep different names.

Agent

Unifying names across two classes whose operations only superficially match silently misleads future readers. The agent reads `findById` on both and assumes equivalent behaviour; when one has implicit side effects the other doesn't, the trap is hard to detect statically. Verify behaviour matches before unifying names.