Search code examples
coding-style

Why Feature Envy sample code in the clean code book is a code smell?


I am reading clean code and in the 17 section it is said that when a class is more interested in the fields and functions of another class it means that feature envy. then the following sample exist there:

public class HourlyPayCalculator {
public Money calculateWeeklyPay(HourlyEmployee e) {
int tenthRate = e.getTenthRate().getPennies();
int tenthsWorked = e.getTenthsWorked();
int straightTime = Math.min(400, tenthsWorked);
int overTime = Math.max(0, tenthsWorked - straightTime);
int straightPay = straightTime * tenthRate;
int overtimePay = (int)Math.round(overTime*tenthRate*1.5); 
return new Money(straightPay + overtimePay);
 }
}

How this sample is a feature envy?

Can anyone make this clear for me?

Thank you in advance.


Solution

  • In your example calculateWeeklyPay is showing signs of feature envy because it's heavily reliant on the internals of the HourlyEmployee class. Instead of asking the HourlyEmployee for its fields and then calculating the pay outside of it, HourlyEmployee class can have a method like calculatePay that performs these calculations internally.

    It can be refactored like this:

    public class HourlyEmployee {
        // ... Other methods and fields ...
    
        public Money calculateWeeklyPay() {
            int tenthRate = this.getTenthRate().getPennies();
            int tenthsWorked = this.getTenthsWorked();
            int straightTime = Math.min(400, tenthsWorked);
            int overTime = Math.max(0, tenthsWorked - straightTime);
            int straightPay = straightTime * tenthRate;
            int overtimePay = (int)Math.round(overTime * tenthRate * 1.5);
            
            return new Money(straightPay + overtimePay);
        }
    }
    
    // And then the HourlyPayCalculator would be simplified:
    public class HourlyPayCalculator {
        public Money calculateWeeklyPay(HourlyEmployee e) {
            return e.calculateWeeklyPay();
        }
    }