Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the Single Responsibility Principle applicable to functions?

According to Robert C. Martin, the SRP states that:

There should never be more than one reason for a class to change.

However, in his book Clean Code, chapter 3: Functions, he shows the following block of code:

    public Money calculatePay(Employee e) throws InvalidEmployeeType {
        switch (e.type) {
            case COMMISSIONED:
                return calculateCommissionedPay(e);
            case HOURLY:
                return calculateHourlyPay(e);
            case SALARIED:
                return calculateSalariedPay(e);
            default:
                throw new InvalidEmployeeType(e.type);
        }
    }

And then states:

There are several problems with this function. First, it’s large, and when new employee types are added, it will grow. Second, it very clearly does more than one thing. Third, it violates the Single Responsibility Principle (SRP) because there is more than one reason for it to change. [emphasis mine]

Firstly, I thought the SRP was defined for classes, but it turns out it's also applicable to functions. Secondly, how is that this function has more than one reason to change? I can only see it changing because of a change on Employee.

like image 979
Enrique Avatar asked Mar 08 '15 17:03

Enrique


1 Answers

You can think about the method above as an object that belongs to the following class:

class PaymentCalculator implements Function<Employee, Money> {
  Money apply(Employee) {
    switch (e.type) {
            case COMMISSIONED:
                return calculateCommissionedPay(e);
            case HOURLY:
                return calculateHourlyPay(e);
            case SALARIED:
                return calculateSalariedPay(e);
            default:
                throw new InvalidEmployeeType(e.type);
        }  
  }
}

Then let's try to find the reasons why this class might be modified:

  1. changes in employee types salary
  2. changes in calculations logic (new parameters as an employee position, experience, etc)

For at least those two types of changes you will be forced to make corrections in this method. It's worth mentioning that SRP goal is to achieve low coupling and high cohesion. To understand the benefit of this try to imagine that you have a big system with hundreds classes and methods like this: calculatePay, calculateVacation, createDepartment, etc. And all those classes and methods have the code like this. Will it be easy to make changes?

P.S. Once you see long if-else or case statements you can start thinking about SRP.

like image 117
Stephen L. Avatar answered Nov 17 '22 09:11

Stephen L.