employee modules

The Single Responsibility Principle (Part 2)

Previously, we discovered how the Single Responsibility Principle (SRP), the first of the SOLID Principles, instructs us on how we should and shouldn’t write our classes. 

I reused the canonical example from Robert C. Martin’s excellent book ‘Clean Architecture‘: We have a Employee class in a payroll application responsible to three separate ‘actors‘—the IT, Accounting and Operations departments. And herein lay the problem—any changes to the Employee class made by one of the departments might be at odds with the needs of one of the other departments. A modification of a shared helper method by the programmers in Accounting consequently broke expected behaviour in the Operations department. 

employee

SRP violations can express themselves as subtle, damaging bugs.

What are we to do? How do we fix this?

Let’s refresh our minds of what the (restated) SRP was about:

Each module should only be responsible to one actor.

How do we make class Employee responsible to only one actor? We may need to break it up into smaller classes, each solely accountable to a single department’s needs.

How should we go about this? 

Well, the public methods of Employee are CalculatePay(), ReportHours() and Save(). Each is responsible to a different actor—the Accounting, Operations and IT departments, respectively.

It makes sense to break up Employee along these identified responsibilities, the public methods. But what should we name the new classes?

The names of modules should reflect the work that they do. In our case, it would make sense to have, say, a PayCalculator, an HoursReporter and an EmployeeSaver. Those names are pretty good, I think. No? 

Aside – No Noise Words

Please, please give your classes descriptive names that leave out meaningless noise words. Consider PayCalculationHelper, HoursReportManager and EmployeeSavingService. Do these names convey more information than PayCalculator, HoursReporter and EmployeeSaver? No, not really. Their wishy-washy naming reduces clarity and obscures meaning. Indeed, these unclear names may, over time, attract code that does not strictly belong. The often-used ‘Helper‘, ‘Manager‘ and ‘Service‘ noise words detract rather than clarify a classes purpose and are best left out.

 

The classes after breaking up of class Employee:

employee modules

A couple of salient points:

  1. Notice that PayCalculator and HoursReporter each has their own, independent version of GetRegularHours(). We got into trouble because a change to GetRegularHours() by the Accounting department broke expected behaviour in Operations. Both PayCalculator and HoursReporter now have separate, independently changeable copies of GetRegularHours(). The Accounting and Operations departments calculate regular employee hours worked differently. We are forgoing DRY (Don’t Repeat Yourself) because it is appropriate, even required, for us to do so. 
  2. Our new collection of classes must not reference and call one another. If they do, then we will have re-established the original SRP violation.

Next: The SRP is about Cohesion

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply