Feature Envy
Function Strategy | Multi-metric
A method that accesses another class's data more than it accesses its own. The method "envies" a neighbour class, suggesting it belongs there instead.
Detection Rule
ATFD > 5 AND ATFD > local_accesses
| Condition | Meaning |
|---|---|
| ATFD > 5 | Substantial foreign data access (not just one or two reads) |
| ATFD > local_accesses | Foreign accesses exceed this.x accesses — more interested in others than in self |
Access counting rules
ATFD (foreign) counts obj.field member expressions where the base is an external identifier (not this or super). Method calls like obj.method() are explicitly excluded — only data accesses count.
local_accesses counts this.x accesses where the access is not a method call (i.e., this.method() is excluded).
TypeScript Example
class PriceCalculator {
calculateDiscount(order: Order, customer: Customer) {
// Foreign accesses (ATFD=7):
const base = order.basePrice; // +1
const qty = order.quantity; // +1
const country = order.shipCountry; // +1
const tier = customer.tier; // +1
const loyalty = customer.loyaltyPts; // +1
const created = customer.createdAt; // +1
const override = customer.discountOverride; // +1
// Local accesses (local=1):
const rate = this.defaultRate; // +1
return base * (1 - rate);
}
}
// ATFD=7 > 5 ✓ AND ATFD=7 > local=1 ✓ → Feature Envy
Remediation
- Move Method — move
calculateDiscountintoOrderorCustomer, whichever supplies more data. - Introduce Parameter Object — bundle the accessed fields into a single object and pass it in.
- Extract Helper — if the method spans multiple foreign classes, extract one piece per class.