# Rename Method

> Change a method's name to say what it does, using a forwarding alias when callers cannot all be updated at once.

- kind: technique
- category: simplifying-method-calls
- aliases: Change Function Declaration, Rename Function
- canonical: https://aipatterns.dev/refactoring/techniques/rename-method
- inspired-by: https://refactoring.guru/rename-method

## Problem

A method's name does not describe what it does. It may describe how it works, use a stale term from an old version of the domain, or be so vague (`process`, `handle`, `doIt`) that every reader opens the body to find out. Comments at call sites try to compensate.

## Solution

**Give the method a name that states its effect or result in domain terms, and update every caller.** For published APIs, keep the old name as a deprecated alias for a transition period.

## Before

```ts
class SubscriptionService {
  // Moves the plan to the next tier and prorates the charge
  async chk(sub: Subscription, plan: PlanId): Promise<Invoice> {
    const credit = this.unusedCredit(sub);
    sub.plan = plan;
    return this.billing.charge(sub.customerId, this.priceOf(plan) - credit);
  }
}

await subscriptions.chk(sub, "pro");
```

## After

```ts
class SubscriptionService {
  async upgradeWithProration(sub: Subscription, plan: PlanId): Promise<Invoice> {
    const credit = this.unusedCredit(sub);
    sub.plan = plan;
    return this.billing.charge(sub.customerId, this.priceOf(plan) - credit);
  }

  /** @deprecated Use upgradeWithProration. Remove after v4. */
  chk(sub: Subscription, plan: PlanId): Promise<Invoice> {
    return this.upgradeWithProration(sub, plan);
  }
}

await subscriptions.upgradeWithProration(sub, "pro");
```

## Why

- Code is read far more than written. A good name removes a trip into the body for every reader.
- The explanatory comment becomes unnecessary.
- Consistent names across classes reveal duplication and let you unify interfaces.

## Steps

1. Check whether the method is declared in a superclass, subclass or interface. A rename must cover every declaration in the hierarchy.
2. If your tooling supports a safe rename (an IDE or language server rename), use it and run the tests. You are done.
3. Otherwise, add a new method with the new name and copy the body into it. Make the old method delegate to the new one. Run the tests.
4. Update callers to the new name, a few at a time, running the tests as you go.
5. When nothing calls the old name, delete it. For a public API, mark it deprecated and delete it in a later release.

## Watch out

- Text search misses dynamic calls: string-based dispatch, reflection, RPC method names, serialized event names, template bindings. Search for the string, not only the symbol.
- Renaming a method that is part of a public package, REST route or message contract is a breaking change. Keep the alias.
- Do not rename to describe the implementation (`loopAndSumCharges`). Name the outcome (`totalCharges`).
- If you cannot find a good name, the method may do two things. Try [Separate Query from Modifier](https://aipatterns.dev/refactoring/techniques/separate-query-from-modifier.md) or [Extract Method](https://aipatterns.dev/refactoring/techniques/extract-method.md) first.
- Rename is its own inverse.

## Related

- Helps with [Alternative Classes with Different Interfaces](https://aipatterns.dev/refactoring/smells/alternative-classes-with-different-interfaces.md) by aligning names, and removes [Comments](https://aipatterns.dev/refactoring/smells/comments.md) that explain bad names.
- Often done together with [Add Parameter](https://aipatterns.dev/refactoring/techniques/add-parameter.md) or [Remove Parameter](https://aipatterns.dev/refactoring/techniques/remove-parameter.md).

## Agent checklist

- [ ] All declarations in the class hierarchy and interfaces were renamed together.
- [ ] String-based references (reflection, routes, configs, mocks) were searched for and updated.
- [ ] Public APIs keep a deprecated alias.
- [ ] The new name describes the result, not the mechanics.
