The Single Responsibility Principle – Your Powerful Ally to Focused Classes

Single Responsibility Principle

 

We’ve got SOLID’s Single Responsibility Principle all wrong. Again and again, I hear developers complaining that this principle is being violated because some function does more than one thing. Indeed, that rule exists, but it’s not the Single Responsibility Principle!

Functions should do only one thing. Yet the SOLID Principles operate at the level of the class, not the function. Classes have more moving parts than mere functions. Classes are made up of internal data structures and exposed functions that act on those data structures.

The Single Responsibility Principle

We are continuing from yesterday’s article on the purpose of the SOLID Principles. SOLID is an acronym made up from the initial letters of the five principles that compose it. The S in SOLID represents the Single Responsibility Principle (SRP). We will investigate the SRP today.

The Single Responsibility Principle states that 

Each module should only have a single reason to change.

Reading this definition, a couple of questions come to mind:

  1. What is a module? and
  2. What is a reason to change?

module is a mid-level programming construct combining functions with data structures. In object-oriented programming (OOP) languages, modules are classes (e.g. C#, C++, Java). In some procedural languages, modules may be as simple as files containing functions that belong together (e.g. Python).

What about a reason to change? The ‘discoverer’ of the SRP, Robert C. Martin, claims that this principle is not about each module having only a single responsibility per se. He made the point that the SRP is concerned with responsibilities to people, or better, a group of people or stakeholders. Given that terms like stakeholders don’t relate directly to programming, Martin falls back to the UML term ‘Actor’.

A better definition for the Single Responsibility Principle would then be 

Each module should only be responsible to one actor.

This new definition isn’t much clearer. An example is in order. 

Violating the SRP and its Effects – An Example

In his excellent book, ‘Clean Architecture‘, Robert C. Martin uses the following Employee class to demonstrate a typical SRP violation:

employee class

Class Employee has three public methods (+ signs):

  •  CalculatePay()
  •  ReportHours()
  •  Save()

and one private method (- sign):

  • GetRegularHours()

 

The developers were careful and kept the code DRY (Don’t Repeat Yourself). Therefore GetRegularHours() is used by both CalculatePay() and ReportHours().

Who are the actors that Employee‘s public methods are responsible to? 

Save() is probably the easiest to determine the actor for: It’s us – software developers and DBAs. Saving Employee state falls within the responsibility of the IT department of the business. We are the ones who decide to change how the employee state is persisted: Maybe we want to migrate from stored procedures to an ORM or even swap out an SQL database for a non-SQL one.

What about CalculatePay()? Payment of employees is a financial concern and falls within the realm of the Accounting department and their accountants.

And ReportHours()? Reporting on the number of hours an employee has worked is an HR function. It belongs to the Operations department. 

We have three different actors demanding changes in the Employee class. Unsurprisingly, the Employee class violates the SRP. 

So what? No big deal, right? Maybe, maybe not.

The Head of the Accounting department requests developers make a minor tweak to the treatment of non-overtime hours. And one developer goes ahead and makes the change to GetRegularHours() but forgets to check where else GetRegularHours() is called. A small oversight that will have far-reaching consequences.

Unfortunately, this change has also affected ReportHours() used by the Operations department. When an HR minion finally tracks down the problem, several months have passed, and the Operations department is millions of dollars over budget! Ouch.

So, how do we make the Employee class SRP-compliant? We’ll look into that next time

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply