In object-oriented design, generally, data should be packaged together with the processes that use that data. The Feature Envy anti-pattern is one where a method seems more interested in a class other than the one it actually is in. The most common focus of envy is the data. The fundamental rule of thumb is to put things together that change together. Data and the behavior that references that data usually change together.
Impact
- Reduced maintainability.
- Envied data is likely to be accessed by several external classes. This makes the data critical.
- Methods envying the data can become unnecessarily large.
- Failure to keep data and functionality together is a violation of encapsulation. The envied class can tend to act like a Data Class simply providing access to its data.
- Distribution of system’s intelligence tends to be imbalanced.
- The Feature envy method possibly also uses data from its own class in addition to envied data. This means refactoring can become complex as the functionality now is a combination of those that belong to separate classes. It becomes hard to simply move this method over to the envied class.
Characteristics
- The method makes excessive use of attributes of other classes.
- The method uses far more attributes of other classes than its own.
- It uses those foreign attributes to implement functionality that should ideally, belong to foreign classes.
- The envied data accessed by methods affected by this anti-pattern belong to very few other classes.
Example(s)
- Method M1 ( ) ofTextArea application is affected by Feature Envy.
- TextArea has M1, M2, and M3 as member variables.
- The method Method 1 ( ) doesn’t use M1, M2, and M3 but uses members from the following Foreign Data Provider 4 members from FDP 2 3 members from FDP 1 1
members from FDP 3 7 members from FDP 4 - Thereby it’s more interested in other classes data than its own class.
Guidelines
- Methods shall access functionality of other classes rather than accessing their attributes directly.
- If a Feature Envy affected method is not accessing any of its own data, move it to the envied class.
- If a Feature Envy affected method is making use of its own data partially then break it down and move the envied functionality into the envied class. This will also balance the distribution of system intelligence.
- If a Feature Envy affected method is accessing data from two or more classes, move it to the class that is envied the most. After that point, break the functionality such that the part that belongs to another envied class is moved into that class.