Single responsibility principle

Published Jun 08, 2017

As the first of the SOLID principles it really seems to be the most underrated but mostly mentioned principle of all.

SRP applies to redundancy. But that is only half of the truth. The correct way is to say: SRP applies to semantic redundancy.

The point is that every artefact should have a unique semantic. If it has a unqiue semantic it is clearly separated from other unqiue semantics so the representing code will only change if the semantic changes.

So if you see syntax redundancy then the next to check for semantic redundancy. You have to see syntactical redundancy as an indicator for refactoring. But you may run into problems if you start too soon. There are four possible situations:

You do not assume a redundancy - There is no redundancy
In this case you would leave the code unchanged and everything is fine.

You do not assume a redundacy - There is a redundancy
In this case you would leave the code unchanged but messy. This is called error type I.

You do assume a redundancy - There is in fact a redundancy
In this case you would change the code and improve the code quality.

You do assume a redundancy - There is no redundancy
In this case you would change the code and introduce new problems. This is known as the error type II.

Your goal has to be to at least make as less type II errors as possible and find as much semantic redundancies as possible.

To make the right decision (leaving the code as it is or change it) you have to do a thought experiment that involves business domain knowledge. You have to ask yourself: Should both code change for the same reason? This is sometimes hard to identifiy and you may ask the business man to participate in the thought experiment.

SRP is more powerful and consistent as the DRY principle. It does not only refer to "what is written" but also to "what it really means". DRY (Don't repeat yourself) only adresses syntactical redundancy where you can lead wrong so you may run into the error type II.

As DRY only adresses syntactical redundancy you often miss real redundancy as well as semantics can be expressed in several syntactical ways: (a very very simple example)

if (!(a || b)) {
   x();
} else {
   y();
}

is the same as

if (!a && !b) {
   x();
} else {
   y();
}

is the same as

if (a || b) {
y();
} else {
x();
}

Semantic redundancy is real pain and is sometimes hard to identify.

My way to minimize semantic redundancy is to gather detail domain knowledge and visualize the domain model as an UML diagram. Any architectural code is derived from it in a very strict way. This relates to DDD (Domain driven design).

Discover and read more posts from Arne Lewinski
get started