Build fluency in the vocabulary of a method that reaches into another class's data more than its own.
0 / 5 completed
1 / 5
At standup, a dev mentions a method in a Cart class that repeatedly reaches into a Customer object's internal fields to compute a loyalty discount, using far more of the Customer's data than anything belonging to Cart itself. What is this code smell called?
Feature envy is exactly this: it is a code smell where a method in one class repeatedly reaches into another class's internal data or methods far more than it uses anything belonging to its own class, suggesting the method actually belongs on the other class instead. A hash collision is an unrelated hash-table concept about two keys sharing a bucket. This reach-into-another-class's-data-more-than-its-own pattern is exactly why feature envy signals that logic is misplaced and should move closer to the data it operates on.
2 / 5
During a design review, the team moves a loyalty-discount calculation from Cart into a new method directly on the Customer class, specifically because the calculation used almost entirely Customer's own fields anyway. Which capability does this provide?
Moving the method here provides logic placed next to the data it actually operates on, since moving the calculation onto Customer means it can use Customer's own fields directly instead of reaching across from Cart into Customer's internals. Leaving the calculation on Cart while it reaches into Customer's fields keeps the logic further from the data it depends on most, and a future change to Customer's internal fields is more likely to break the reaching-in code in Cart. This move-logic-next-to-its-data behavior is exactly why fixing feature envy means relocating the method to the class whose data it actually needs.
3 / 5
In a code review, a dev notices a calculateLoyaltyDiscount method lives on the Cart class, yet it reads five separate fields directly off a Customer object and uses nothing from Cart itself except to call the method. What does this represent?
This is feature envy, since the method reaches into Customer's data far more than it uses anything from its own Cart class, suggesting it belongs on Customer instead. A cache eviction policy is an unrelated concept about discarded cache entries. This reach-into-another-class's-fields pattern is exactly the kind of smell a reviewer flags once a method's real dependencies point somewhere other than the class it currently lives on.
4 / 5
An incident report shows a loyalty-discount calculation broke in production after Customer's internal fields were restructured, because the calculateLoyaltyDiscount method lived on Cart and reached directly into those Customer fields instead of living on Customer itself where the restructuring would have been accounted for. What practice would prevent this?
Moving the calculateLoyaltyDiscount method onto the Customer class puts it next to the data it actually depends on instead of reaching in from Cart and breaking whenever that data is restructured. Continuing to keep the calculateLoyaltyDiscount method on Cart reaching into Customer's fields regardless of how often a restructuring of those fields breaks it is exactly what caused the breakage described in this incident. This relocate-the-method approach is the standard fix once feature envy is confirmed between a method and the data it actually uses.
5 / 5
During a PR review, a teammate asks why the team relocates a method with feature envy to the class whose data it uses instead of simply adding getter methods on Customer so Cart can keep reaching in more cleanly. What is the reasoning?
Relocating the method to Customer eliminates the cross-class reach entirely, so a future change to Customer's internal fields only has to account for methods that already live on Customer, while adding getters on Customer for Cart to call still leaves the calculation logic on Cart, reaching across through the getters instead of directly, and still breaking whenever Customer's internals change shape. This is exactly why relocating a method with feature envy to the class it actually depends on is the standard fix, rather than papering over the reach with getters.