Sunday, June 23, 2013

The insidious SRP

SRP - the Single Responsibility Principle - says that a class should have one and only one responsiblity, and hence only one reason to change. While both the mechanics and rationale for this principle is really easy to understand it is very often violated, even by very skilled programmers.

The StringCalculator kata is a famous coding kata designed by Roy Osherove. The goal is basically to calculate the sum of a series of numbers delimited according to certain rules. By doing the kata you will practice test-first programming and refactoring.

Right on the instructions page are links to screencasts done by people implementing StringCalculator in realtime. As you would expect, the videos show fluent, test-driven implementations of the problem in different languages.

Lets assume we are working with step 1 and 2 of the kata. We should be able to add zero or more numbers in a string, delimited by a comma. A typical nicely recursive implementation looks like this:

While this code is probably a lot more simple than you would see in your day job, it is not immediately obvious what it does. And the reason for that is that it violates SRP!

The add() method have two responsibilities:
  1. Adding numbers
  2. Locating and parsing numbers in a String
It is really a bit hard to tell what code takes responsibility for which concept, and that is the whole problem.

Lets refactor the responsibilities of this problem into two parts.
  1. StringCalculator: Adding numbers, as before
  2. NumberArray: Locating and parsing numbers in a String

The same code, only possible to understand in a glance. The second responsibility is explicitly taken care of by another class. The API of NumberArray feels familiar and straightforward, so for the calculation business there is no need to get involved in that code.

When the kata continues with more parsing rules, all changes will go into the NumberArray class. The logic of adding numbers does not change.

As a programmer, you should always be looking for hidden and implicit concepts in your code. Just by extracting such a simple concept as finding numbers between the commas in a String, you can make yourself and the future you a huge favour!

No comments:

Post a Comment