Behavior is reaching outward
Feature envy usually means the method is better placed on the object whose data it keeps interrogating.
Feature envy and data clumps often appear together. Feature envy happens when a method seems more interested in another object's data than in its own. Data clumps happen when the same small group of fields travels together repeatedly. Both suggest weak object boundaries and missed modeling opportunities.
In an e-commerce domain, shipping address fields, money-related values, or customer contact details often travel together across methods and layers. When behavior keeps pulling those values apart from the outside, the codebase becomes harder to model and easier to duplicate incorrectly.
Feature envy is often a responsibility placement problem. A method repeatedly pulls data out of another object because the current object does not naturally own the behavior. Data clumps are often a modeling problem. The system keeps passing related fields separately because no one promoted them into a meaningful concept.
For Java developers, both problems are useful because they point toward better object boundaries. A method can often move closer to the data it envies. A repeated field group can often become a value object, request model, or domain concept.
The real payoff is not elegance for its own sake. It is fewer duplicated rules and clearer ownership of business meaning.
Feature envy usually means the method is better placed on the object whose data it keeps interrogating.
Data clumps often indicate a missing value object or missing domain concept.
Without stronger concepts, the same validation and derivation logic starts appearing in many places.
package org.javaomnibus.ecommerce.antipatterns;
public final class ShipmentLabelService {
public String buildLabel(Order order) {
return order.getStreet() + ", " + order.getCity() + ", " + order.getPostalCode() + ", " + order.getCountry();
}
}
public final class TaxService {
public TaxCategory resolve(String street, String city, String postalCode, String country) {
return TaxCategory.DOMESTIC;
}
}
Not every repeated pair of fields deserves a new type. Promote a cluster into a real concept when it carries shared meaning, validation, or behavior.