Skip to content

Feature Envy

Flag a method whose cross-class field and method accesses to another class outnumber accesses to its own, signalling that the behavior lives at the wrong address and should be relocated to the class whose data it operates on.

Core Idea

Feature envy is the object-oriented code smell in which a method is more interested in another class's data than its own: its body is dominated by accesses to the other class's fields and methods, and its coupling to that class exceeds coupling to its own. The method is in the wrong place. Named by Fowler, it marks responsibility misplacement — not a runtime error but a maintenance tax, since every change to the data owner's interior propagates into the envious method.

How would you explain it like I'm…

Always Using a Friend's Toys

Imagine you keep reaching into your friend's backpack to do your homework with her pencils, her paper, and her ruler. It would be simpler if that homework just belonged to your friend. In computer code, when one part keeps using another part's stuff, it's called Feature Envy, and the fix is to move the job to where the stuff lives.

The Job in the Wrong Place

In some programs, code is organized into 'classes', each holding its own information and its own jobs. Feature Envy is when a job in one class keeps reaching into another class's information much more than its own. It's a sign the job is in the wrong place. It doesn't make the program crash, but every time the other class changes, this job has to be fixed too. The cure is to move the job into the class whose information it uses.

Misplaced-Method Code Smell

Feature Envy is a 'code smell', a warning sign in object-oriented code, named by Martin Fowler in Refactoring. It happens when a method in one class mostly works with another class's data and methods instead of its own. The behavior lives in one place while the data it uses lives in another, so changes to the other class keep forcing changes to this method. A simple test: if a method touches another class far more than its own, it probably belongs there. The usual fix is Move Method, relocating the method (or the envious part) to the class that owns the data. This follows the 'Tell, Don't Ask' idea: tell an object to do work rather than pulling out its insides.

 

Feature Envy, named by Martin Fowler in Refactoring (1999), is an object-oriented code smell in which a method is more coupled to another class's interface than to its own. Its signature has four parts: a data-owner class with state and behavior; an outsider method dominated by accesses to that state; a locality mismatch, with behavior in one class and its data in another; and change propagation, where edits to the data owner disproportionately force edits to the envious method. It signals misplaced responsibility and appears as a maintenance cost, not a runtime error. The diagnostic is fan-out: when cross-class accesses greatly outnumber in-class ones, the method belongs on the envied class. The remedy is Move Method, which relocates the method or its envious portion so the coupling becomes internal. It is common in anemic domain models, god controllers in MVC, and utility classes that pull internals out of domain objects. The guiding principles are Tell-Don't-Ask and the Law of Demeter: tell objects to do work instead of extracting their internals.

Scope of Application

Lives wherever object-oriented responsibility is allocated across classes and a method can end up at the wrong address.

  • Anemic domain models — logic pooled in service classes reaching into passive data classes.
  • God controllers in MVC — a controller method reaching deep into model state.
  • Manager-class accretion — an OrderManager computing what Order should own.
  • Utility-class drift — helpers picking at a domain object's internals rather than delegating.
  • Cross-service reads — one service making many small reads against another's state.

Clarity

The name converts a reviewer's vague unease into a locally detectable diagnosis with a bound remedy: this method envies class B, so move it to B. It makes legible that correctness and responsibility placement are different axes — the method can produce right output while living at the wrong address, so the problem registers as a maintenance tax, not a bug. It gives coupling a direction and a locality the bare notion lacks.

Manages Complexity

Judging responsibility placement across a codebase is a whole-graph problem; feature envy collapses it to a local one, readable from a single method's body via one countable scalar — cross-class fan-out versus in-class fan-out. Recognition and remedy arrive together (the smell binds to Move Method), and a static analyzer can surface candidates mechanically. The correctness-versus-placement split lets the reviewer read the cost off the fan-out alone.

Abstract Reasoning

The smell licenses a recognize-locate-relocate chain: a diagnostic counting move (cross-class fan-out signals misplacement), a boundary-drawing move separating correctness from responsibility placement and the smell from god class and shotgun surgery siblings, a predictive move recasting the cost as a future stream of forced edits, and an interventionist move (Move Method closes the change-propagation path).

Knowledge Transfer

Within software design the smell transfers as mechanism — its four-part signature, countable diagnostic, and Move Method remedy carry across anemic models, god controllers, and even microservice boundaries, with Tell-Don't-Ask and the Law of Demeter travelling along. Beyond software the portable structure is the parent Cohesion (software / module-level) — behavior should live with the data it operates on — of which feature envy is one named OO violation. The Move-Method/fan-out apparatus stays home; invoking "feature envy" for org design is analogy in naming.

Relationships to Other Abstractions

Local relationship map for Feature EnvyParents appear above the current abstraction, mutual partners to the right, and children below. Node labels state whether each abstraction is prime or domain-specific; colors identify relation types.Feature EnvyDOMAINPrime abstraction: Coupling — includesCouplingPRIMEDomain-specific abstraction: Code Smell — is a kind ofCode SmellDOMAIN

Current abstraction Feature Envy Domain-specific

Parents (2) — outgoing typed relations

  • Feature Envy is a kind of Code Smell Domain-specific

    Feature Envy is the code-smell species whose cross-class access pattern provides defeasible evidence that a method's responsibility resides on the wrong class.

  • Feature Envy includes Coupling Prime

    Outbound dependence on another class's state and behavior is the measurable coupling constituent from which feature envy is diagnosed.

Hierarchy paths (5) — routes to 5 parentless roots

Neighborhood in Abstraction Space

Feature Envy sits in a sparse region of the domain-specific corpus (87th percentile for distinctiveness): few abstractions share its structure, so a faithful description tends to retrieve it precisely.

Family — Distributed Systems Theorems & Fallacies (19 abstractions)

Nearest neighbors

Computed from structural-signature embeddings · 2026-10-25