09
Feature Envy
Symptom
A method on class A reaches deeply into class B's data via getters, then computes something B should compute.
Goal
Methods live with the data they care about — B owns the logic over B's fields.
Smellier version
class Order {
totalWeight() {
return this.items.reduce((s, i) => s + i.unitWeight * i.qty, 0);
}
}Fresher versionclass Item { weight() { return this.unitWeight * this.qty; } }
class Order { totalWeight() { return this.items.reduce((s, i) => s + i.weight(), 0); } }Savings
Encapsulation tightens, getters can shrink or disappear, and the method's name clarifies once it's on the right class.
Note
Domain logic lives where it's least expected; B's internals leak through public surfaces just to support A's method.